日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

5.8fork父子进程

發(fā)布時間:2023/11/27 生活经验 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 5.8fork父子进程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
  1. 實驗4-2:fork父子進程

  • 實驗?zāi)康?#xff1a;

理解fork創(chuàng)建子進程的本質(zhì)

?

  • 實驗要求:

    1、按如下要求編寫程序:

(1)、打開一個有內(nèi)容的文件;

(2)、調(diào)用fork創(chuàng)建子進程;

(3)、讀文件的第一個字符輸出打印出來;

(4)、看看父進程和子進程分別讀到的字符是什么

2、按如下要求編寫程序:

(1)、調(diào)用fork創(chuàng)建子進程;

(2)、打開一個有內(nèi)容的文件;

(3)、讀文件的第一個字符輸出打印出來;

(4)、看看父進程和子進程分別讀到的字符是什么

3、比較1和2的區(qū)別

?

  • 實驗步驟:
    • 父進程:parent.c

      #include <sys/types.h>

      #include <signal.h>

      #include <unistd.h>

      #include <stdio.h>

      ?

      static volatile sig_atomic_t sigflag;

      static sigset_t newmask, oldmask, zeromask;

      /* signal handler for SIGUSR1 and SIGUSR2 */

      static void sig_usr(int signo)

      {

      sigflag = 1;

      return;

      }

      void TELL_WAIT()

      {

      if(signal(SIGUSR1, sig_usr) == SIG_ERR)

      printf("signal SIGUSR1 error\n");

      if(signal(SIGUSR2, sig_usr) == SIG_ERR)

      printf("signal SIGUSR2 error\n");

      ?

      sigemptyset(&zeromask);

      ?

      sigemptyset(&newmask);

      sigaddset(&newmask, SIGUSR1);

      sigaddset(&newmask, SIGUSR2);

      ?

      /* block SIGUSR1 and SIGUSR2, and save current signal mask */

      if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)

      printf("SIG_BLOCK error\n");

      }

      void TELL_PARENT(pid_t pid)

      {

      kill(pid, SIGUSR2); /* tell parent we are done */

      }

      void WAIT_PARENT()

      {

      while(sigflag == 0)

      sigsuspend(&zeromask); /* wait for parent */

      ?

      sigflag = 0;

      ?

      /* reset signal mask */

      if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)

      printf("SIG_SETMASK error\n");

      }

      void TELL_CHILD(pid_t pid)

      {

      kill(pid, SIGUSR1);

      }

      void WAIT_CHILD()

      {

      while(sigflag == 0)

      sigsuspend(&zeromask); /* wait for parent */

      ?

      sigflag = 0;

      ?

      /* reset signal mask */

      if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)

      printf("SIG_SETMASK error\n");

      }

      void do_task(char *task_str)

      {

      printf("%s\n", task_str);

      }

      /* parent goes first program */

      int main()

      {

      pid_t pid;

      ?

      TELL_WAIT();

      ?

      pid = fork();

      if(pid < 0) {

      printf("fork error\n");

      }

      else if(pid == 0) {

      WAIT_PARENT();

      do_task("child task\n");

      }

      else {

      do_task("parent task\n");

      TELL_CHILD(pid);

      }

      ?

      return 0;

      }

      ?

?

  • 子進程child.c:

    #include <sys/types.h>

    #include <signal.h>

    #include <unistd.h>

    #include <stdio.h>

    ?

    static volatile sig_atomic_t sigflag;

    static sigset_t newmask, oldmask, zeromask;

    /* signal handler for SIGUSR1 and SIGUSR2 */

    static void sig_usr(int signo)

    {

    sigflag = 1;

    return;

    }

    void TELL_WAIT()

    {

    if(signal(SIGUSR1, sig_usr) == SIG_ERR)

    printf("signal SIGUSR1 error\n");

    if(signal(SIGUSR2, sig_usr) == SIG_ERR)

    printf("signal SIGUSR2 error\n");

    ?

    sigemptyset(&zeromask);

    ?

    sigemptyset(&newmask);

    sigaddset(&newmask, SIGUSR1);

    sigaddset(&newmask, SIGUSR2);

    ?

    /* block SIGUSR1 and SIGUSR2, and save current signal mask */

    if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)

    printf("SIG_BLOCK error\n");

    }

    void TELL_PARENT(pid_t pid)

    {

    kill(pid, SIGUSR2); /* tell parent we are done */

    }

    void WAIT_PARENT()

    {

    while(sigflag == 0)

    sigsuspend(&zeromask); /* wait for parent */

    ?

    sigflag = 0;

    ?

    /* reset signal mask */

    if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)

    printf("SIG_SETMASK error\n");

    }

    void TELL_CHILD(pid_t pid)

    {

    kill(pid, SIGUSR1);

    }

    void WAIT_CHILD()

    {

    while(sigflag == 0)

    sigsuspend(&zeromask); /* wait for parent */

    ?

    sigflag = 0;

    ?

    /* reset signal mask */

    if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)

    printf("SIG_SETMASK error\n");

    }

    void do_task(char *task_str)

    {

    printf("%s\n", task_str);

    }

    ?

    ?

    /* child goes first program*/

    int main()

    {

    pid_t pid;

    ?

    TELL_WAIT();

    ?

    pid = fork();

    if(pid < 0) {

    printf("fork error\n");

    }

    else if(pid == 0) {

    do_task("child task\n");

    TELL_PARENT(getppid());

    }

    else {

    WAIT_CHILD();

    do_task("parent task\n");

    }

    ?

    return 0;

    }

  • 編譯運行:

4、實驗結(jié)論

fork創(chuàng)建進程之后再打開文件,文件在主進程和子進程分別執(zhí)行打開

打開文件的文件記錄表分別被父子進程創(chuàng)建,對應(yīng)有2個讀寫位置

所以2個進程都讀到第一個字符a

?

  • 實驗總結(jié):

    1、多個進程對同一文件讀操作不會相互干擾

    2、這是建立在各個進程都執(zhí)行open文件前提下的

    3、每open一次,系統(tǒng)會在該進程的用戶空間創(chuàng)建一個文件記錄表,記錄了打開文件的狀態(tài)信息(包括文件讀寫偏移位置)

?

實驗心得:

????Linux是出了名的多線程的操作實驗,該實驗實現(xiàn)一個父進程和一個子進程,兩者實現(xiàn)信息的交流。上面是我的實現(xiàn)過程。謝謝。

?

轉(zhuǎn)載于:https://www.cnblogs.com/FORFISH/p/4201826.html

總結(jié)

以上是生活随笔為你收集整理的5.8fork父子进程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。