pipe 半双工_linux进程间通信之管道(无名管道pipe)实现全双工双向通信
管道是什么:
1. 管道只能用于具有親緣關系的進程之間通信。
2.管道是一種單工或者說半雙工的通信方式,傳遞信息的方向是固定的,只能由一端傳遞到另一端。
頭文件及函數原型:
#include
int pipe(int fd[2]);
當用pipe 創建管道后,兩個文件描述符fd[0],fd[1]就可以使用了,其中fd[0]用于讀取,fd[1]用于寫入。調用管道pipe返回值0表示成功,返回值-1表示失敗。
pipe函數創建管道后,接著fork出子進程,子進程繼承父進程管道。
代碼舉例來看:
#include
#include
#include
#include
#include
#define MAX_DATA_LEN 256
#define DELAY_TIME 1
int main() {
pid_t pid;
char buf[MAX_DATA_LEN];
const char *data="Pipe Test";
int real_read,real_write;
int pipe_fd[2];
memset((void*)buf,0,sizeof(buf));
if(pipe(pipe_fd)<0){
perror("Pipe create error!\n");
exit(1);
}
if ((pid=fork())<0) {
perror("Fork error!\n");
exit(1);
} else if (pid==0) {
close(pipe_fd[1]);
sleep(DELAY_TIME*3);
if ((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0) {
printf("Child receive %d bytes from pipe: '%s'.\n",real_read,buf);
}
close(pipe_fd[0]);
exit(0);
} else {
close(pipe_fd[0]);
sleep(DELAY_TIME);
if ((real_write=write(pipe_fd[1],data,strlen(data)))>0) {
printf("Parent write %d bytes into pipe: '%s'.\n",real_write,data);
}
close(pipe_fd[1]);
waitpid(pid,NULL,0);
exit(0);
}
}
復制代碼
運行輸出:
Parent write 9 bytes into pipe: 'Pipe Test'.
Child receive 9 bytes from pipe: 'Pipe Test'.
上述代碼只能從父進程向子進程傳遞,如何從子進程向父進程傳遞呢?我們看到父進程關閉了管道讀取端“close(pipe_fd[0]);”,子進程關閉了管道寫入端“close(pipe_fd[1]);”,如果取消關閉這兩個端,是否能夠實現子進程向父進程傳遞呢。
父進程先發送,子進程接收,然后子進程再發送,父進程再接收,實現全雙工互相通信,期望運行結果如下:
Parent write 9 bytes into pipe: 'Pipe Test'.
Child receive 9 bytes from pipe: 'Pipe Test'.
Child write 9 bytes from pipe: 'Pipe Test'.
Parent receive 9 bytes from pipe: 'Pipe Test'.
修改代碼如下:
#include
#include
#include
#include
#include
#define MAX_DATA_LEN 256
#define DELAY_TIME 1
int main() {
pid_t pid;
char buf[MAX_DATA_LEN];
const char *data="Pipe Test";
int real_read,real_write;
int pipe_fd[2];
memset((void*)buf,0,sizeof(buf));
if(pipe(pipe_fd)<0){
perror("Pipe create error!\n");
exit(1);
}
if ((pid=fork())<0) {
perror("Fork error!\n");
exit(1);
} else if (pid==0) {
//close(pipe_fd[1]);
sleep(DELAY_TIME*3);
if ((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0) {
printf("Child receive %d bytes from pipe: '%s'.\n",real_read,buf);
}
if ((real_write=write(pipe_fd[1],data,strlen(data)))>0) {
printf("Child write %d bytes into pipe: '%s'.\n",real_write,data);
}
close(pipe_fd[0]);
exit(0);
} else {
//close(pipe_fd[0]);
sleep(DELAY_TIME);
if ((real_write=write(pipe_fd[1],data,strlen(data)))>0) {
printf("Parent write %d bytes into pipe: '%s'.\n",real_write,data);
}
if ((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0) {
printf("Parent receive %d bytes from pipe: '%s'.\n",real_read,buf);
}
close(pipe_fd[1]);
waitpid(pid,NULL,0);
exit(0);
}
}
復制代碼
但是實際運行如下:
Parent write 9 bytes into pipe: 'Pipe Test'.
Parent receive 9 bytes from pipe: 'Pipe Test'.
可以看到,父進程發送的數據被父進程自己接收了,子進程讀不到數據被阻塞了。顯然這種方法不行。
因為管道是單工的,只能固定從一個方向傳遞到另一個方向。
要實現互相通信,一個管道是不行的,可以創建兩個管道,一個管道是父寫子讀,另一個是子寫父讀。
代碼如下:
#include
#include
#include
#include
#include
#define MAX_DATA_LEN 256
#define DELAY_TIME 1
int main() {
pid_t pid;
char buf[MAX_DATA_LEN];
const char *data="Pipe Test";
int real_read,real_write;
int pipe_fd[2],pipe_fd2[2];
memset((void*)buf,0,sizeof(buf));
if(pipe(pipe_fd)<0){
perror("Pipe create error!\n");
exit(1);
}
if(pipe(pipe_fd2)<0){
perror("Pipe create error!\n");
exit(1);
}
if ((pid=fork())<0) {
perror("Fork error!\n");
exit(1);
} else if (pid==0) {
close(pipe_fd[1]);
close(pipe_fd2[0]);
sleep(DELAY_TIME*3);
if ((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0) {
printf("Child receive %d bytes from pipe: '%s'.\n",real_read,buf);
}
if ((real_write=write(pipe_fd2[1],data,strlen(data)))>0) {
printf("Child write %d bytes into pipe: '%s'.\n",real_write,data);
}
close(pipe_fd[0]);
close(pipe_fd2[1]);
exit(0);
} else {
close(pipe_fd[0]);
close(pipe_fd2[1]);
sleep(DELAY_TIME);
if ((real_write=write(pipe_fd[1],data,strlen(data)))>0) {
printf("Parent write %d bytes into pipe: '%s'.\n",real_write,data);
}
if ((real_read=read(pipe_fd2[0],buf,MAX_DATA_LEN))>0) {
printf("Parent??receive %d bytes from pipe: '%s'.\n",real_read,buf);
}
close(pipe_fd[1]);
close(pipe_fd2[0]);
waitpid(pid,NULL,0);
exit(0);
}
}
復制代碼
運行結果:
Parent write 9 bytes into pipe: 'Pipe Test'.
Child receive 9 bytes from pipe: 'Pipe Test'.
Child write 9 bytes into pipe: 'Pipe Test'.
Parent??receive 9 bytes from pipe: 'Pipe Test'.
可以看到,創建了兩個管道 “int pipe_fd[2],pipe_fd2[2];”,
pipe_fd 是父寫子讀,pipe_fd2是子寫父讀,通過兩個管道,實現了進程的全雙工互相通信。
總結
以上是生活随笔為你收集整理的pipe 半双工_linux进程间通信之管道(无名管道pipe)实现全双工双向通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 定义16进制_java数据类型
- 下一篇: Arch Linux中的Pacman命令