要求
利用管道技术实现父子进程间通信,父进程以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;
}
运行结果