利用管道技术实现父子进程间通信,具体流程:父进程以3秒为周期接收用户输入并发送到子进程,子进程接收到信息后显示并回传,父进程接收到回传信息后显示。父子进程在通信过程中采用信号中断处理方式进行处理,接收到“exit”字符串后父子进程均退出。(采用SIGUSR1或SIGUSR2信号)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
pid_t pid;
int fildes1[2],fildes2[2];
void timefunc(int sig)
{
char buf[1024];
memset(buf,0,sizeof(buf));
if(read(STDIN_FILENO,buf,sizeof(buf))<0) / /接收键盘输入
{
fprintf(stderr,"read error");
exit(0);
}
if(write(fildes1[1],buf,strlen(buf))<0) //父进程写
{
fprintf(stderr,"write error");
exit(0);
}
kill(pid,SIGUSR2); //kill用于向任何进程组或进程发送信号。
signal(SIGALRM,timefunc);
alarm(3);
}
void userfunc1(int sig)
{
char buf[1024];
memset(buf,0,sizeof(buf));
if(read(fildes2[0],buf,sizeof(buf))<0) //父进程读
{
fprintf(stderr,"father read error");
exit(0);
}
signal(SIGUSR1,userfunc1);
if(strncmp(buf,"exit",4)==0)exit(0);
fprintf(stderr,"father recv :%s",buf);
}
void userfunc2(int sig)
{
char buf[1024];
memset(buf,0,sizeof(buf));
if(read(fildes1[0],buf,sizeof(buf))<0) // 子进程读
{
fprintf(stderr,"child read error");
exit(0);
}
if(write(fildes2[1],buf,sizeof(buf))<0) //子进程写
{
fprintf(stderr,"child write error");
exit(0);
}
kill(getppid(),SIGUSR1);
signal(SIGUSR2,userfunc2);
if(strncmp("exit",buf,4)==0)exit(0);
fprintf(stderr,"child recv :%s",buf);
}
int main()
{
if(pipe(fildes1)<0 || pipe(fildes2)<0)
{
fprintf(stderr,"pipe error");
exit(0);
}
pid = fork(); //fork在父进程中返回子进程id 在子进程中返回0
if(pid>0)
{
close(fildes1[0]); //管道1 父进程写 关闭读
close(fildes2[1]); //管道2 父进程读 关闭写
signal(SIGALRM,timefunc);
signal(SIGUSR1,userfunc1);
alarm(3);
//alarm也称为闹钟函数,它可以在进程中设置一个定时器,当定时器指定的时间到时,
//它向进程发送SIGALRM信号
}else if(pid==0)
{
close(fildes1[1]); //管道1 子进程读 关闭写
close(fildes2[0]); //管道2 子进程写 关闭读
signal(SIGUSR2,userfunc2);
}else
{
perror("fork error");
exit(0);
}
while(1);
return 0;
}