进程间通信的简单示例-管道+信号

要求
利用管道技术实现父子进程间通信,父进程以3秒为周期接收用户输入并发送到子进程,子进程接收到信息后显示并回传,父进程接收到回传信息后显示。父子进程在通信过程中采用信号中断处理方式进行处理,接收到“exit”字符串后父子进程均退出

想法

  • 两个pipe分别代表“父->子”、“子->父”的通信
  • 利用SIGALRM信号定时以3s为周期接收用户输入并将数据放入"父->子"pipe
  • 父进程放入数据后发送SIGUSR2信号通知子进程,子进程捕捉后读取
  • 子进程读取成功后发送SIGUSR2信号通知父进程,父进程捕捉后读取

代码实现

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

int pipe_fd1[2];
int pipe_fd2[2];

int pid;
int child_pid;

void err(const char *str)
{
	fprintf(stderr,"%s\n",str);
	exit(1);
}

void usr_action(int sig)
{
	char buf[1024];
	memset(buf,0,sizeof(buf));
	if (sig == SIGUSR1)
	{
	
		if (0 < read(pipe_fd2[0],buf,1024))
		{
			printf("father read: %s\n",buf);
			if(buf[4] == '\n' && 0 == strncmp(buf,"exit",4))
			{
				kill(child_pid,SIGKILL);
				wait(NULL);
				exit(0);
			}
		}	
		else
		{
			err("father read err");
		}
		memset(buf,0,sizeof(buf));
	}
	else
	{
	

		if (0 < read(pipe_fd1[0],buf,1024))
		{
			printf("child read: %s\n",buf);
		}
		else
		{
			err("child read err");
		}
		if (0 > write(pipe_fd2[1],buf,1024))
		{
			err("child write err");
		}
		kill(pid,SIGUSR1);
		memset(buf,0,sizeof(buf));
	}
		
}

void alarm_action(int sig)
{
	char buf[1024];
	memset(buf,0,sizeof(buf));
	fgets(buf,1024,stdin);
	if (0 > write(pipe_fd1[1],buf,1024))
	{
		err("father write err");
	}
	kill(child_pid,SIGUSR2);
	alarm(3);
}

int main()
{
	if (pipe(pipe_fd1) < 0)
		err("create pipe1 error");
	if (pipe(pipe_fd2) < 0)
		err("create pipe2 error");
	pid = getpid();

	if ((child_pid = fork()) < 0)
	{
		err("fork err");
	}
	else if (child_pid > 0)
	{
		close(pipe_fd1[0]);
		close(pipe_fd2[1]);
		signal(SIGUSR1,usr_action);
		signal(SIGALRM, alarm_action);
		alarm(3);
		while(1);	
	}
	else
	{
		close(pipe_fd2[0]);
		close(pipe_fd1[1]);
		signal(SIGUSR2,usr_action);
		while(1);
	}

	return 0;
}

运行结果
请添加图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值