网站备案接入服务商,网站方案制作,新手做网站什么类型,网络运维个人工作总结进程间通信系列--管道 管道可以说是最古老的IPC形式#xff0c;所谓管道#xff0c;是指进程间建立的一条通信的通道#xff0c;从本质上看#xff0c;管道是UNIX文件概念的推广管道通信的介质是文件#xff0c;先看一下管道的特点#xff1a; 1.管道的特点#xff1a; … 进程间通信系列--管道 管道可以说是最古老的IPC形式所谓管道是指进程间建立的一条通信的通道从本质上看管道是UNIX文件概念的推广管道通信的介质是文件先看一下管道的特点 1.管道的特点 1管道是半双工的数据只能向一个方向流动需要双方通信时需要建立起两个管道 2无名管道只能用于父子进程或者兄弟进程之间具有亲缘关系的进程后来发展了FIFO也称有名管道 3单独构成一种独立的文件系统管道对于管道两端的进程而言就是一个文件但它不是普通的文件它不属于某种文件系统而是自立门户单独构成一种文件系统并且只存在与内存中。 4数据的读出和写入一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾并且每次都是从缓冲区的头部读出数据。 2.无名管道API及操作 头文件#include unistd.h 数据成员int pipe_fd[2]; 管道创建int pipe(int fd[2]) 该函数创建的管道的两端处于一个进程中间在实际应用中没有太大意义因此一个进程在由pipe()创建管道后一般再fork一个子进程然后通过管道实现父子进程间的通信因此也不难推出只要两个进程中存在亲缘关系这里的亲缘关系指的是具有共同的祖先都可以采用管道方式来进行通信。 管道读写 管道两端可分别用描述字fd[0]以及fd[1]来描述管道读端fd[0]管道写端fd[1]; 读管道规则 关闭管道的写端close (fd[WRITE]); 读出read(fd[READ],string,strlen(string)); 读出后关闭管道的读端close(fd[REAd]); 写管道规则 关闭管道的读端close(fd[REAd]); 写入write(fd[WRITE],string,strlen(string)); 写入后关闭管道的写端close (fd[WRITE]); 下面练习一个简单的单管道通信 父进程写数据子进程负责读出数据 [cpp] view plaincopy /************** * readtest.c * **************/ #include unistd.h #include sys/types.h #include errno.h #define READ 0 #define WRITE 1 main() { int pipe_fd[2]; pid_t pid; char r_buf[100]; char w_buf[32]; char* p_wbuf; int r_num; int cmd; memset(r_buf,0,sizeof(r_buf)); memset(w_buf,0,sizeof(r_buf)); p_wbufw_buf; if(pipe(pipe_fd)0) { printf(pipe create error ); return -1; } if((pidfork())0) //子进程读 { close(pipe_fd[WRITE]); sleep(3); //确保父进程关闭写端 r_numread(pipe_fd[READ],r_buf,100); printf( read num is %d the data read from the pipe is %s /n,r_num,r_buf); close(pipe_fd[READ]); exit(); } else if(pid0) //父进程写 { close(pipe_fd[READ]); strcpy(w_buf,hello world!/n); if(write(pipe_fd[WRITE],w_buf,strlen(w_buf))-1) printf(parent write over/n ); close(pipe_fd[WRITE]); printf(parent close fd[WRITE] over /n); sleep(10); } } 编译运行看到预期结果 3.利用两个管道进行双向通信 1创建两个管道管道1(父-子)管道2(子-父) 2fork()产生子进程 3父进程close(fd1[READ]); close(fd2[WRITE]); 4子进程close(fd1[WRITE]); close(fd2[READ]); 下面做一个练习是利用双向通信实现父子进程协作把整数x从1加到10 [cpp] view plaincopy #include unistd.h #include sys/stat.h #include sys/types.h #include stdio.h #include fcntl.h #define MAXLINE 1024 #define READ 0 #define WRITE 1 main(void) { int x; pid_t pid; int pipe1[2],pipe2[2]; /*初始化管道*/ pipe(pipe1); pipe(pipe2); pid fork(); if(pid 0) { printf(create process error!/n); exit(1); } if(pid 0) //子进程 { close(pipe1[WRITE]); close(pipe2[READ]); do { read(pipe1[READ],x,sizeof(int)); printf(child %d read: %d/n,getpid(),x); write(pipe2[WRITE],x,sizeof(int)); }while(x9); //读写完成后,关闭管道 close(pipe1[READ]); close(pipe2[WRITE]); exit(0); } else if(pid 0) //父进程 { close(pipe2[WRITE]); close(pipe1[READ]); x 1; //每次循环向管道1 的1 端写入变量X 的值,并从 //管道2 的0 端读一整数写入X 再对X 加1直到X 大于10 do{ write(pipe1[WRITE],x,sizeof(int)); read(pipe2[READ],x,sizeof(int)); printf(parent %d read: %d/n,getpid(),x); }while(x9); //读写完成后,关闭管道 close(pipe1[WRITE]); close(pipe2[READ]); waitpid(pid,NULL,0); exit(0); } }