zoukankan      html  css  js  c++  java
  • 一个进程通信的问题

    一、问题的描述如下:

    父进程创建子进程1,然后创建子进程2,子进程1将自己的pid乘以2,用可靠信号发送给子进程2,子进程2收到之后,发送给父进程。

    二、问题分析:

         首先,进程间发送数据可以用sigaction/sigqueue来完成;可靠信号是kill -l里面 32-64的那些。问题是,子进程1如何知道子进程2的pid?如果知道了,那么这个问题将迎刃而解。

    三、问题解决。

          当父进程创建子进程1后,等待,创建子进程2后,父进程将进程2的pid发送给进程1,这样便可以不断的发送数据了。

          代码如下:(子进程会继承父进程注册的信号,所以父进程--子进程1,子进程1-子进程2,子进程2-父进程 的三次发送信号的处理函数都在一开始便进行了注册。)

          

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <errno.h>
     4 #include <fcntl.h>
     5 #include <unistd.h>
     6 #include <sys/stat.h>
     7 #include <sys/types.h>
     8 #include <sys/types.h>
     9 #include <signal.h>
    10 #include <string.h>
    11 #include <sys/wait.h>
    12 // 要求是子进程1发送给2,但是1如何获得2到pid呢?
    13 void handle(int num, siginfo_t * sigdata, void *p)
    14 {
    15     if(num == SIGRTMIN+1){
    16         printf("recv data:%d from pid2
    ",sigdata->si_value.sival_int);    
    17     }
    18     if(num == SIGRTMIN+2){
    19         // 收到父进程发过来到信号,解析出pid2,然后把pid*2发送给pid2
    20         printf("get pid2` from father %d
    ",sigdata->si_value.sival_int);
    21         union sigval senddata;
    22         senddata.sival_int = getpid()*2;            
    23         if(sigqueue(sigdata->si_value.sival_int,SIGRTMIN+3,senddata) == -1){
    24             perror("error");
    25         }                    
    26     }
    27     if(num == SIGRTMIN+3){
    28         pid_t pid = getppid();
    29            union sigval senddata;
    30         senddata.sival_int = sigdata->si_value.sival_int;
    31         printf("get data %d from pid1
    ", senddata.sival_int);
    32         if(sigqueue(pid,SIGRTMIN+1,senddata) == -1){
    33             perror("error");
    34         }
    35     }
    36 }
    37 int main(void)
    38 {
    39     pid_t pidArray[10] = {0};
    40     pid_t pid;
    41     int i;
    42     struct sigaction sigaf;
    43     sigaf.sa_sigaction = handle;        
    44     sigaf.sa_flags = SA_SIGINFO;
    45     sigaction(SIGRTMIN+1,&sigaf,NULL);
    46     
    47     sigaction(SIGRTMIN+2,&sigaf,NULL);
    48 
    49     sigaction(SIGRTMIN+3,&sigaf,NULL);
    50     for(i = 0; i < 2; ++i){
    51         pidArray[i] = pid = fork();
    52         if(pid == 0){
    53             break; // 子进程不生子进程
    54         }
    55         else if(pid > 0){
    56         }
    57     }
    58     if(pid > 0){ // 父进程
    59         // 将pid2发送给pid1
    60         while(pidArray[2] == 0){
    61             
    62         }
    63         union sigval sendtoone;
    64         sendtoone.sival_int = pidArray[1];
    65         if(sigqueue(pidArray[0],SIGRTMIN+2,sendtoone) == -1){
    66             perror("error");            
    67         }
    68         sleep(10);
    69     }
    70 
    71     if(pid ==0 && i == 0){ // 子进程1
    72         sleep(4);
    73         exit(0);
    74     }
    75     if(pid == 0 && i == 1){ // 子进程2
    76         sleep(4);
    77         exit(0);
    78     }
    79     int mypid = 0;
    80     while((mypid = waitpid(-1,NULL,WNOHANG)) > 0){
    81         printf("%d 结束
    ", mypid);
    82     }
    83     return 0;
    84 }
  • 相关阅读:
    Linux各个目录的作用及内容
    发现未授权登录用户怎么办
    开启GodMode
    通过域名方式决定使用哪个数据库的方式分享
    openerp-server.conf 中配置 dbfilter 参数无效的解决办法
    OpenERP7.0 忘记admin管理员密码解决办法
    DEB方式在UBUNTU安装ODOO 8.0
    解决apt-get的E: Could not get lock /var/lib/dpkg/lock方法
    Ubuntu 11.04 (Natty) 已经停止支持 但可以使用old-releases源了
    How to get the url of a page in OpenERP?
  • 原文地址:https://www.cnblogs.com/tntboom/p/4491797.html
Copyright © 2011-2022 走看看