zoukankan      html  css  js  c++  java
  • Linux父子进程同步

    /*
     * 使用信号实现父子进程之间的同步
     *
     * TELL_WAIT(): set things up for TELL_xxx & WAIT_xxx 
     * TELL_PARENT():  tell parent we are done
     * WAIT_PARENT():  wait for parent
     * TELL_CHILD(): tell child we are done
     * WAIT_CHILD(): wait for child
     *
     * SIGUSR1: the signal parent sends to child
     * SIGUSR2: the signal child sends to parent
     */

     
     

    #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 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;
    }

    /*
     * 使用管道实现父子进程同步 
     *
     * 父进程在调用TELL_CHILD 时经由上一个管道写一个字符p,子进程在
     * 调用TELL_PARENT时,经由下一个管道写一个字符c。相应的WAIT_XXX
     * 函数调用read读一个字符,没有读到字符时阻塞(睡眠等待)。
     *
     */

     

     
     

    static int pfd1[2], pfd[2];

    void TELL_WAIT()
    {
        if(pipe(pfd1) < 0 || pipe(pfd2) < 0)
            printf("pipe error\n");
    }

    void TELL_PARENT(pid_t pid)
    {
        if(write(pfd2[1], "c", 1) != 1)
            printf("write error\n");
    }

    void WAIT_PARENT()
    {
        char c;
        if(read(pfd1[0], &c, 1) != 1)
            printf("read error\n");
        if(!= 'p')
            printf("WAIT_PARENT: incorrect data\n");
    }

    void TELL_CHILD(pid_t pid)
    {
        if(write(pfd1[1], "p", 1) != 1)
            printf("write error\n");
    }


    void WAIT_CHILD()
    {
        char c;
        if(read(pfd1[0], &c, 1) != 1)
            printf("read error\n");
        if(!= 'c')
            printf("WAIT_CHILD: incorrect data\n");
    }

    转自:http://blog.chinaunix.net/space.php?uid=20196318&do=blog&id=28793

  • 相关阅读:
    完整性检查工具Nabou
    Linux下使用网上银行
    戏说Linux商用数据库
    开源数据库“五虎将”
    搜寻Linux软件实用指南
    认识Linux瘦客户机
    一款开源Office软件---Lotus Symphony在Linux系统下的应用
    Leetcode-967 Numbers With Same Consecutive Differences(连续差相同的数字)
    Leetcode-965 Univalued Binary Tree(单值二叉树)
    Leetcode-966 Vowel Spellchecker(元音拼写检查器)
  • 原文地址:https://www.cnblogs.com/viviancc/p/2318433.html
Copyright © 2011-2022 走看看