进程间通信IPC --pipe
最近期末考试,也快考完了。三天预习一门离散数学,预习累了,没事干,外边的课也不上了。可谓是无聊透顶。
于是就拿起《APUE》看看,正好随手翻到了,进程间通信--管道,那就来学习学习,复习之余也可以找找乐子,言归正传。
进线程之间通信的手段很多,公认的有13种,不清楚的自己百度吧,今天来谈谈最古老的之一管道通信,详细来说是无名管道通信,pipe.
#include <unistd.h>
int pipe(int pipefd[2]);
顾名思义这还真是个管道,起初只能建造一条管道,从父进程通向子进程传送东西,和"水管“ 一样,将需要告诉子进程的东西从管道塞进去,然后子进程从父进程接受内容,后来人们发现这种方式一个最明显的缺陷就是,子进程有事想给父进程说怎麼办?所以人们小小扩展了下这个程序,一次创建两个管道,一个从父进程到子进程,一个从子进程到父进程。这阳极也可以通信了,其中含有两个整形的数组。就是两个文件流指针。分别管制输入和输出,一般是0为读取端,1为输入端。
贴上一个基础使用代码
#include<stdio.h>
#include<apue.h>
#define MAXLINE 120
int main(){
int fd[2];
pid_t pid;
char line[MAXLINE];
if(pipe(fd)< 0){
printf("pipe error\n");
}
pid = fork();
if(pid < 0){
printf("fork error\n");
}else if(pid == 0){
close(fd[1]);
read(fd[0],line,MAXLINE);
printf("%s\n",line);
close(fd[0]);
exit(0);
}else{
close(fd[0]);
if(write(fd[1],"hello world",12) != 12){
printf("write error\n");
}
}
父进程给子进程说hello world 子进程从管道读取并且打印到终端
醉了居然还有该死的水印。。。。。
下面在贴上一个将通信做成函数的管道通信小例子
#include<stdio.h>
#include<apue.h>
static int pfd1[2],pfd2[2];
void TELL_WAIT(void)
{
if(pipe(pfd1) < 0||pipe(pfd2) < 0){
printf("pipe error\n");
}
}
void TELL_PARENT(pid_t pid){
if(write(pfd2[1],"c",1) != 1){
printf("write error\n");
}
}
void WAIT_PARENT(void){
char c;
if(read(pfd1[0],&c,1) != 1){
printf("read error\n");
}
printf("***%c\n",c);
if(c != 'p'){
printf("WAIT_PARENT : incorret data\n");
}
}
void TELL_CHILD(pid_t pid){
char c;
if(write(pfd1[1],"p",1) != 1){
printf("read error\n");
}
}
void WAIT_CHILD(void){
char c;
if(read(pfd2[0],&c,1) != 1){
printf("read error\n");
}
printf("***%c\n",c);
if(c != 'c'){
printf("WAIT_CHILD:incorrect data\n");
}
}
int main()
{
pid_t chid ;
TELL_WAIT();
chid = fork();
if(chid < 0){
printf("fork error\n");
}else if(chid == 0){
printf("son start:\n");
WAIT_PARENT();
TELL_PARENT(chid);
printf("son is end\n");
exit(0);
}else{
printf("father start :\n");
TELL_CHILD(chid);
WAIT_CHILD();
printf("father end :\n");
}
}
结果是
由此还可以看出,在管道没有东西可以读取的时候就把自己挂起了。。。。。。。自挂东南枝