1. 程式人生 > >linux之無名管道

linux之無名管道

操作 char fork stdio.h 緩沖 stdin fgets 打開 open

1、查看命令: man 2 pipe

2.頭文件:#include <unistd.h>

3、函數原型: int pipe(int pipefd[2]);
a、pipefd[2] :無名管道的兩個文件描述符,int型的數組,大小為2,pipefd[0]為讀端,pipefd[1]為寫端

4、返回值:
成功:返回0
失敗:返回-1

5、函數特點:
無名管道是最簡單的常用於一對一的親緣進程間通信的方式,既然說是管道,所以可以想象成一條水管,連接兩個進程
一個進程負責輸入數據,另一個進程負責接收數據,反過來也一樣。

6、無名管道的缺點:
a、沒有名字,因此無法使用open()打開
b、只能用於親緣進程間(如父子進程、兄弟進程、祖孫進程等)通信
c、半雙工工作方式,讀寫端是分開的,pipefd[0]為讀端,pipefd[1]為寫端
d、寫入操作不具有原子性,因此只能用於一對一的簡單通信
e、不能用lseek()來定位

下面上代碼

#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<stdlib.h>
#include<wait.h>
#include<string.h>

#define LENGTH 50 //字符數組的大小
int main(int argc,char **argv)
{
int status;//進程退出時用
int pipefd[2];//用於保存無名管道的兩個文件描述符,pipefd[0]為讀端,pipefd[1]為寫端

int ret;
pid_t pid;

/*創建無名管道,需要在fork()之前創建,這樣子進程才能繼承無名管道*/
ret = pipe(pipefd);
if(ret == -1)//創建失敗
{
perror("pipe");
exit(1);//異常退出
}

pid = fork();//創建子進程

if(pid != 0)//父進程,負責從無名管道中讀取數據
{
wait(&status);//等待子進程退出
char buf[LENGTH];
read(pipefd[0],buf,sizeof(buf));//從無名管道中讀取數據,read函數會阻塞
printf("來自子進程的信息: %s",buf);

}


if(pid == 0)//子進程,負責把數據寫入無名管道
{
char buf[LENGTH];
bzero(buf,sizeof(buf));//清空緩沖區
puts("請輸入你要發送給父進程的內容:");
fgets(buf,sizeof(buf),stdin);
write(pipefd[1],buf,sizeof(buf));//把數據寫入無名管道
exit(0);//子進程退出
}

close(pipefd[0]);//關閉無名管道中的讀端
close(pipefd[1]);//關閉無名管道中的寫端
return 0;
}

linux之無名管道