05多进程间使用信号进行通信

#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/wait.h>


#if 1
/*
要求:
	3、信号可靠信号不可靠信号相关
	编程程序,要去实现如下功能:
	父进程创建子进程1和子进程2、子进程1向子进程2发送可靠信号,
	并传送额外数据为子进程1的pid*2;
	子进程2接受可靠信号的值,并发送给父进程,父进程把接受的值
	进行打印。
	提示:用sigqueue和sigaction实现

分析:
	1因为孩子1的pid和孩子2的pid全部在父进程中
	2父进程把孩子2的pid,发给孩子1
	3孩子1有了孩子2的pid,孩子1就可以给孩子2发送信号了。
	
	父--->子1---->子2---->父
*/

// kill -l 查看信号

int pidArray[10];//使用全局变量缓存子进程id

 void myhandle(int num, siginfo_t *st, void *p)
 {
 	//子进程1接收到了信号
 	if(num == SIGRTMIN+1)
 	{
 		printf("孩子1收到信号值:%d \n", st->si_value.sival_int);
 		//获取到子进程2的pid
 		pidArray[1] = st->si_value.sival_int;
 	}
 	
 	//子进程2接收到了信号
 	if(num == SIGRTMIN+2)
 	{
 		//孩子2收到信号
		printf("孩子2收到信号,值:%d \n", st->si_value.sival_int);
		//子进程的pid * 2
		pidArray[3] = st->si_value.sival_int;
 		
 	}
 	
 	//父进程接收到了信号
 	if(num == SIGRTMIN+3)
 	{
 		//父进程接收到了信号
		printf("父进程收到信号,值:%d \n", st->si_value.sival_int);
		printf("父进程中的pid[0]:%d pid[1]:%d \n", pidArray[0], pidArray[1]);
 	}
 	
 }
int test()
{
	int i = 0;
	struct sigaction act;
	act.sa_sigaction = myhandle;
	act.sa_flags = SA_SIGINFO;//表示信号要传输信息
	
	if(sigaction(SIGRTMIN+1, &act, NULL) == -1){
		perror("func sigaction err");
		return -1;	
	}
	if(sigaction(SIGRTMIN+2, &act, NULL) == -1){
		perror("func sigaction err");
		return -1;	
	}
	if(sigaction(SIGRTMIN+3, &act, NULL) == -1){
		perror("func sigaction err");
		return -1;	
	}
	
	
	int pid = 0;
	//连续创建2 个子进程
	for (i = 0; i < 2; i++)
	{
		//父进程可以把所有孩子的id缓存下来
		pidArray[i] = pid = fork();
		if(pid == 0)
		{
			break;//如果是孩子,不参与fork	
		}
		else if (pid > 0) 
		{
			;
		}
		
	}
	
	
	
	//子进程1向子进程2发送 子进程1的pid*2
	if (pid == 0 && i == 0) 
	{
		printf("子进程1运行\n");
		printf("子进程1 sleep\n");
		//sleep是可中断的睡眠,只要linux内核发信号,进程就会醒来
		printf("进程1 sleep 剩余时间为 %d\n",sleep(5));
		printf("子进程1sleep被打断后,全局变量有值了,即子进程1拿到了子进程2的pid:%d\n",pidArray[1]);
		
		//添加额外数据
		union sigval mysigval;
		mysigval.sival_int = getpid()*2;
		printf("子进程1给进程2发送信号getpid()*2:%d  \n", getpid()*2);
		//向子进程2发送消息
		if(sigqueue(pidArray[1], SIGRTMIN+2, mysigval) < 0 )
		{
			perror("func sigqueue err");
			return -1;			
		}
		printf("子进程1给子进程2发完信号啦,即将退出........\n");
		exit(0);
	}
	
	//子进程2 向父进程发送信号
	
	if (pid == 0 && i == 1) 
	{
		printf("进程2 sleep 剩余时间为 %d\n",sleep(20));
		printf("子进程2睡眠醒来,开始发送信号\n");
		
		//添加额外数据
		union sigval mysigval;
		mysigval.sival_int = pidArray[3];
		printf("子进程2给父进程发送信号pidArray[3]:%d  \n", pidArray[3]);
		
		
		//子进程2向父进程发送消息
		if(sigqueue(getppid(), SIGRTMIN+3, mysigval) < 0 )
		{
			perror("func sigqueue err");
			return -1;			
		}
		printf("子进程2给父进程发完信号啦,即将退出........\n");
		exit(0);	
	}
    
    
    //父进程向子进程1发送子进程2的pid
	if (pid > 0) 
	{
		printf("父进程运行\n");
		//父进程给进程1发信号 把进程2的pid发过去
		
		//添加额外数据
		union sigval mysigval;
		mysigval.sival_int = pidArray[1];
		
		//向子进程1发送消息
		if(sigqueue(pidArray[0], SIGRTMIN+1, mysigval) < 0 )
		{
			perror("func sigqueue err");
			return -1;			
		}
		printf("父进程给子进程1发完信号啦........\n");
		
	}
	               
    sleep(2);
    int mypid = 0;
    //非阻塞等待所有的子进程退出
    while ((mypid = waitpid(-1, NULL, WNOHANG)) > 0 )
    {
    	 printf("子进程退出pid:%d \n", mypid);
    }
    printf("hello........\n");  
    return 0; 
          
}
#endif

在这里插入图片描述

进行单独测试父子进程通信,并没有出现以上问题

#if 0

void myhandle(int num, siginfo_t *st, void *p)
 {
 	//子进程1接收到了信号
 	if(num == SIGRTMIN+1)
 	{
 		printf("收到信号值:%d \n", st->si_value.sival_int);
 	}
 }

int  test()
{
	struct sigaction act;
	act.sa_sigaction = myhandle;
	act.sa_flags = SA_SIGINFO;//表示信号要传输信息
	
	if(sigaction(SIGRTMIN+1, &act, NULL) == -1){
		perror("func sigaction err");
		return -1;	
	}

	
	int pid = 0;
	pid = fork();
	
	//子进程给父进程发送信号
	if (pid == 0) 
	{
		//添加额外数据
		union sigval mysigval;
		mysigval.sival_int = 111;
		
		//向子进程1发送消息
		if(sigqueue(getppid(), SIGRTMIN+1, mysigval) < 0 )
		{
			perror("func sigqueue err");
			return -1;			
		}
		exit(0);
	}
	
	sleep(2);
    int mypid = 0;
    //非阻塞等待所有的子进程退出
    while ((mypid = waitpid(-1, NULL, WNOHANG)) > 0 )
    {
    	 printf("子进程退出pid:%d \n", mypid);
    }
    printf("hello........\n");        
    return 0; 
	
}
#endif

int main()
{
	test();
	return 0;
}

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章