[源码]信号可靠信号不可靠信号相关

/* 
 * File:   main.c
 * Author: luv letter
 *
 * Created on 2017年3月14日, 下午4:33
 */


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>


/*
 3、信号可靠信号不可靠信号相关
编程程序,要去实现如下功能:
	父进程创建子进程1和子进程2、子进程1向子进程2发送可靠信号,并传送额外数据为子进程1的pid*2;
	子进程2接受可靠信号的值,并发送给父进程,父进程把接受的值进行打印。
	提示:用sigqueue和sigaction实现
 */
void My_Sigaction(int signum, siginfo_t *st, void *dat)
{
	int ret = 0;
	// 这个是父进程的接收数据信号
	if (SIGRTMIN+1 == signum)
	{
		printf("parent rev signal\n");
		printf("parent rev pid2 signal data = %d\n", st->si_value.sival_int);
	}
	else if (SIGRTMIN == signum)	//并将数据发送给父进程
	{
		printf("child recv signal\n");
		union sigval value;
		printf("My_Sigaction : st->si_value.sival_int = %d\n", st->si_value.sival_int);
		value.sival_int = st->si_value.sival_int;
		ret = sigqueue(getppid(), SIGRTMIN+1, value);
		if (-1 == ret)
		{
			perror("pid2: SIGRTMIN func err sigqueue: ");
			return ;
		}
	}
}


int main(int argc, char** argv)
{
	int ret = 0;
	struct sigaction act;
	sigemptyset(&act.sa_mask);
	act.sa_sigaction = My_Sigaction;
	ret = sigaction(SIGRTMIN+1, &act, NULL);
	if (-1 == ret)
	{
		perror("func err sigaction: ");
		return -1;
	}


	pid_t pid1, pid2;


	///
	//									pid1
	///
	
	pid1 = fork();
	if (-1 == pid1)
	{
		perror("func err fork() pid 1: ");
		return -1;
	}
	else if (0 == pid1) // 子进程 1
	{
		// 1 子进程1向子进程2发送可靠信号,并传送额外数据为子进程1的pid*2;
		// SIGRTMIN+1
		// pid.txt
			// 读取 子进程2 的 pid
			// 用文件读取
		FILE *fp = NULL;
		while (1)
		{
			fp = fopen("pid.txt", "a+");
			if (NULL == fp)
			{
				continue;
			}
			else
			{
				break;
			}
		}
		printf("pid1: 打开文件成功\n");
		// 这里需要字符串转数字
		char revbuf[32] = {0};
		
		while (1)
		{
			char *tmp = fgets(revbuf, sizeof(revbuf), fp);
			if (NULL == tmp)
			{
				printf("pid1: 读取 pid2 中 ...\n");
				continue;
			}
			else 
			{
				printf("pid1: 读取 pid2 成功pid2 = %s\n", revbuf);
				break;
			}
		}
		if (NULL == fp)
		{
			fclose(fp);
			fp = NULL;
		}
		ret = system("rm -rf pid.txt");
		if (-1 == ret)
		{
			printf("pid1: func err system\n");
			return -1;
		}
		
		pid2 = atoi(revbuf);
		printf("pid1: 转化 pid2 为整数成功 = %d\n", (int )pid2 );
		union sigval value;
		value.sival_int = ((int)pid2) * 2;
		printf("pid1: value.sival_int  = %d\n", value.sival_int);
		ret = sigqueue((pid_t)pid2, SIGRTMIN, value);
		if (-1 == ret)
		{
			perror("pid1: func err sigqueue:");
			return -7;
		}
		printf("子进程退出...\n");
		exit(0);
	}
	///
	//									pid2
	///
	pid2 = fork();
	if (-1 == pid2)
	{
		perror("func err fork pid2:");
		return -2;
	}
	else if (0 == pid2) // 子进程 2 
	{
		// 3 接收子进程的信号, 并将数据发送给父进程
		struct sigaction act;
		ret = sigemptyset(&act.sa_mask);
		if (-1 == ret)
		{
			printf("pid2: func err sigemptyset\n");
			return -5;
		}
		act.sa_sigaction = My_Sigaction;
		ret = sigaction(SIGRTMIN, &act, NULL);
		if (-1 == ret)
		{
			perror("pid2: func err sigaction:");
			return -6;
		}
		
		// 1 保存自己的pid, 给子进程使用
		// 这个用文件保存
		FILE *fp = NULL;
		char pid_buf[18] = {0};
		
		fp = fopen("pid.txt", "w+");
		if (NULL == fp)
		{
			printf("pid2: open file failed\n");
			return -3;
		}
		printf("pid2: 打开文件成功...pid2 = %d\n", (int)getpid());
		int pid = (int )getpid();
		sprintf(pid_buf, "%d", pid);
		printf("pid2: pid2 = %s\n", pid_buf);
		ret = fputs(pid_buf, fp);
		if (EOF == ret)
		{
			printf("pid2: write error\n");
			return -4;
		}
		if (NULL != fp)
		{
			fclose(fp);
			fp = NULL;
		}
		printf("pid2: child 2 wait for 5 sec ...\n");
		int n = 5;
		while (n)
		{
			n = sleep(n);
			printf("pid2: child 2 wait end\n");
		}
		printf("pid2: 子进程 2 退出\n");
		exit(0);
	}
	printf("parent wait for 10 sec\n");
	int i = 10;
	while (i)
	{
		i = sleep(i);
		printf("parent wait for 10 sec end \n");
	}
	wait(pid1);
	wait(pid2);
	return (EXIT_SUCCESS);
}



另一套方法

/*
 pid_t pidArray[10];

 void My_Sigaction(int signum, siginfo_t *st, void *dat)
 {
	 if (SIGRTMIN+1 == signum)
	 {
		 // 孩子1 收到了信号
		 
		 printf("孩子 1 收到信号, 他的值是 : %d\n", st->si_value.sival_int);
		 pidArray[1] = st->si_value.sival_int;
	 }
	 else if (SIGRTMIN+2 == signum)
	 {
		 // 进程2 收到信号 
		 
		 printf("孩子 2 收到信号, 他的值是 : %d\n", st->si_value.sival_int);
		 pidArray[3] = st->si_value.sival_int;
	 }
	 else if (SIGRTMIN+3 == signum)
	 {
		 // 父进程收到信号
		 printf("父进程收到信号, 他的大儿子的pid = %d, 他的二儿子的pid = %d\n", pidArray[0], pidArray[1]);
		 printf("二儿子发送的礼物是 = %d\n", st->si_value.sival_int);
	 }
	 else
	 {
		 printf("other signal recv\n");
	 }
 }


int main(void)
{
	int ret = 0;
	
	// 信号发送区
	struct sigaction act;
	act.sa_flags = SA_SIGINFO;
	sigemptyset(&act.sa_mask);
	act.sa_sigaction = My_Sigaction;
	ret = sigaction(SIGRTMIN+1, &act, NULL);
	if (-1 == ret)
	{
		perror("func err sigaction: ");
		return -1;
	}
	
	ret = sigaction(SIGRTMIN+2, &act, NULL);
	if (-1 == ret)
	{
		perror("func err sigaction: ");
		return -2;
	}
	
	ret = sigaction(SIGRTMIN+3, &act, NULL);
	if (-1 == ret)
	{
		perror("func err sigaction: ");
		return -3;
	}
	
	int i = 0;
	pid_t pid = 0;
	for (i = 0; i < 2; i++)
	{
		pidArray[i] = pid = fork();
		if (-1 == pid)
		{
			perror("func err fork:");
			return -4;
		}
		else if (0 == pid)
		{
			break;
		}
	}
	
	// 父进程
	if (pid > 0)
	{
		printf("父进程启动\n");
		// 父进程向子进程 1 发送附加数据(子进程2 的 pid)
		union sigval value;
		value.sival_int = pidArray[1];
		ret = sigqueue(pidArray[0], SIGRTMIN+1, value);
	}
	// 子进程 1 
	if (0 == pid && 0 == i)
	{
		printf("子进程 1 启动\n");
		printf("子进程1 睡眠\n");
		sleep(5);
		printf("子进程1 睡眠醒来\n");
		union sigval value;
		pid_t pid;
		pid = getpid();
		value.sival_int = pid * 2;
		ret = sigqueue(pidArray[1], SIGRTMIN+2, value);
		exit(0);
	}
	// 子进程 2 
	if (0 == pid && 1 == i)
	{
		printf("子进程 2 启动\n");
		printf("子进程 2 睡眠\n");
		sleep(10);
		printf("子进程 2 睡眠醒来\n");
		// 子进程2 发送信号给父进程
		union sigval value;
		value.sival_int = pidArray[3];
		printf("子进程2 给父进程发送信号的数据 %d\n", pidArray[3]);
		ret = sigqueue(getppid(), SIGRTMIN+3, value);
		exit(0);
	}
	sleep(2);
	pid_t mypid = 0;
	while (1)
	{
		while ((mypid = waitpid(-1, NULL, WNOHANG)) > 0)
		{
			printf("pid = %d\n", mypid);
		}
	}
	
	return 0;
}
*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值