一个进程通信的问题

一、问题的描述如下:

父进程创建子进程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\n",sigdata->si_value.sival_int);
17     }
18     if(num == SIGRTMIN+2){
19         // 收到父进程发过来到信号,解析出pid2,然后把pid*2发送给pid2
20         printf("get pid2` from father %d\n",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\n", 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 结束\n", mypid);
82     }
83     return 0;
84 }
时间: 2024-12-11 01:05:31

一个进程通信的问题的相关文章

AF_UNIX域通信(基于socket和pipe的通信,只适于UNIX系统S&C同在一个主机上,用于进程通信)

服务器端: #include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include <sys/socket.h>#include <sys/un.h>#include <stddef.h>char buf[100];void main

Winform and WPF 第二遍双击快捷方式或应用程序打开原来的应用程序而不新建一个实例[进程通信 1]

private void Window_Loaded(object sender, RoutedEventArgs e)         {             Process[] pro = Process.GetProcesses();             int n = pro.Where(p => p.ProcessName.Equals("进程名称")).Count();             if (n > 1)             {      

第七课 进程通信

unix_c_07.txt================第七课 进程通信================一.基本概念------------1. 何为进程间通信~~~~~~~~~~~~~~~~~进程间通信(Interprocess Communication, IPC)是指两个,或多个进程之间进行数据交换的过程.2. 进程间通信分类~~~~~~~~~~~~~~~~~1) 简单进程间通信:命令行参数.环境变量.信号.文件.2) 传统进程间通信:管道(fifo/pipe).3) XSI进程间通信:

进程通信——匿名管道

有的时候在程序的开发过程中,两个进程之间会有数据的交互.信号的机制能够实现进程通信.它通过 “中断--响应” 的异步模式来工作.但作为通信来讲,信号还是远远不够的.因为它不能够携带任何其他的信息.只利用信号机制来实现进程通信显得捉襟见肘,并且信号的优势并不此.所以必须开发新的进程间通信的方法.本文所学习的 "匿名管道" 便是其中的一种最简单的方法. 基本概念 在讲管道的基本概念之前,首先提一个问题.如果让你来设计进程通信的方式,你会怎么做?最简单的方式莫过于两个进程打开同一个文件,这样

Socket进程通信机制

1.Socket通常称为"套接字",用于描述IP地址和端口,是一个通信链的句柄. 2.应用程序通过套接字向网络发出请求或者应答网络请求. 3.Socket既不是一个程序,也不是一种协议,其只是操作系统提供的通信层的一组抽象API. 4.进程通信的相关概念: 网间进程通信要解决的是不同主机进程间相互通信问题.为此,首先要解决的是网间进程标识问题.同一主机上,不同进程可用唯一进程号(Process ID)标识. (1)端口:网络中可以被命名和寻址的通信端口,是操作系统可分配的一种资源,用于

android 远程Service以及AIDL的跨进程通信

在Android中,Service是运行在主线程中的,如果在Service中处理一些耗时的操作,就会导致程序出现ANR. 但如果将本地的Service转换成一个远程的Service,就不会出现这样的问题了. 转换成远程Service非常简单,只需要在注册Service的时候将他的android:process的属性制定成 :remote就可以了. 重新运行项目,你会发现,不会出现ANR了. 为什么将MyService转换成远程Service后就不会导致程序ANR了呢?这是由于,使用了远程Serv

进程通信之内存共享篇

进程通信之_ 内存共享 概念:共享内存是被多个进程共享的一部分物理内存.共享内存是进程间的共享数最快的方法,一个进程向共享内存区域写入数据,共享这个内存区域的所有进程就可以写入数据,所有进程就可以立刻看到其中的内容. 实现步骤;1.创建共享内存,使用shmget函数2.映射共享内存,将这段创建的共享内存映射到具体的进程空间去,使用shmat函数 创建:int shmget (key_t key,int size,int shmflg)key 标识内存功效的键值0/ipc_private.成功返回

Windows进程通信 -- 共享内存

享内存的方式原理就是将一份物理内存映射到不同进程各自的虚拟地址空间上,这样每个进程都可以读取同一份数据,从而实现进程通信.因为是通过内存操作实现通信,因此是一种最高效的数据交换方法. 共享内存在 Windows 中是用 FileMapping 实现的,从具体的实现方法上看主要通过以下几步来实现: 1.调用 CreateFileMapping 创建一个内存文件映射对象: HANDLE CreateFileMapping( HANDLE hFile, // handle to file to map

初始网络进程通信

可以这样说:我们在网络上只做一件事,利用各种软件没完没了的相互通信. 对于单机系统而言,进程在系统中有自己唯一的进程号.但在网络环境下,各主机独立分配的进程号不能唯一标识该进程.例如,主机A赋于某进程号5,在B机中也可以存在5号进程,因此,“5号进程”这句话就没有意义了.而且 操作系统支持的网络协议众多,不同协议的工作方式不同,地址格式也不同.因此,网间进程通信还要解决多重协议的识别问题. 为此,TCP/IP协议为网间进程通信问题建立了IP地址,端口,Socket(套接字)等概念.      (