实例学习Linux进程通信(一)
1、实验一:信号通信
说明:利用信号通信在父子进程及兄弟进程之间进行通信
解决方案:让子进程在结束时,向父进程发送SIGCHLD信号,父进程通过signal()或sigaction()函数来响应子进程的结束。(在一个进程终止或者停止时,将SIGCHLD信号发送给其父进程。)
源码1(阻塞型通信):
#include<stdio.h>
#include<signal.h>
#include<wait.h>
void sigchld_handler(int sig){
pid_t pid;
int status;
for(; (pid = waitpid(-1, &status, WNOHANG)) > 0;){
printf("child %d died: %d\n", pid, status);
printf("parent process received SIGHLD signal success\n");
}
return;
}
void main(){
/*创建子进程*/
int p_id = fork();
if(p_id == 0){/*如果是子进程*/
/*输出子进程信息,休眠一段时间,退出*/
printf("This is child process with pid of %d\n", getpid());
sleep(1);
}else if(p_id > 0){/*父进程*/
/*调用信号处理函数,暂停*/
signal(SIGCHLD, sigchld_handler);
sleep(5);
}else{
/*打印创建进程失败信息,并退出*/
printf("Error!");
return -1;
}
return 0;
}
2、实验二:匿名管道通信
说明:匿名管道只能用于具有亲缘关系的两个进程间通信。
源码:
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#define MAX_LINE 80
void main(){
/*创建一个匿名管道*/
int thePipe[2], ret;
char buf[MAX_LINE + 1];
const char* testbuf = "a test string";
if(pipe(thePipe) == 0){/*管道创建成功,数组第一个元素中的文件描述符供应用程序读取,数组第二个元素中的文件描述符供应用程序写入*/
if(fork() == 0){/*进程创建成功,子进程*/
/*关闭写端,从管道读端读取数据并放入缓冲区*/
close(thePipe[1]);
ret = read(thePipe[0], buf, MAX_LINE);
buf[ret] = 0;
/*输出缓冲区数据,关闭读端,退出*/
printf("Read: %s\n", buf);
close(thePipe[0]);
}else{/*进程创建成功*/
/*关闭读端,向管道写端写入数据*/
close(thePipe[0]);
ret = write(thePipe[1], testbuf, strlen(testbuf));
wait(NULL);/*等待子进程结束*/
close(thePipe[1]);
}
}
}
3、实验三:命名管道通信
说明:命名管道以先进先出形式存在于文件系统中,因此,只要可以访问该文件路径,就能够彼此通过命名管道相互通信。
源码:这段代码写了之后总是有问题,就不贴出来了,但是,很明显,命名管道与匿名管道区别不大,只不过一个只能在父子间通信,一个在任何进程间都能通讯。