java 有名管道_Linux系统编程—有名管道

**▋****1. 管道的概念**

管道,又名「无名管理」,或「匿名管道」,管道是一种非常基本,也是使用非常频繁的IPC方式。

**1.1 管道本质**

- 管道的本质也是一种文件,不过是伪文件,实际上是一块内核缓冲区,大小4K;

- 管道创建以后会产生两个文件描述符,一个是读端,另一个是写端;

- 管道里的数据只能从写端被写入,从读端被读出;

**1.2 管道原理**

管道是内核的一块缓冲区,更具体一些,是一个环形队列。数据从队列的一端写入数据,另一端读出,如下图示:

![img](https://mmbiz.qpic.cn/mmbiz_jpg/YeUmRxGrEBaIPoss68bxNNVaq1ok734WYDzy6yDicUn3vrnZOaXJbf3Qq4ftGG0pSGsbScsxNDnneBT38jGoROA/640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1)

**1.3 管道的优点**

简单

**1.4 管道的缺点**

- 只能单向通信,如果需要双向通信则需要建立两个管道;

- 只能应用于具有血缘关系的进程,如父子进程;

- 缓冲区大小受限,通常为1页,即4k;

**▋****2. 管道的创建**

管道创建三步曲:

a. 父进程调用pipe函数创建管道;

b. 父进程调用fork函数创建子进程;

c. 父进程关闭fd[0],子进程关闭fd[1];

具体如下图所示:

![img](https://mmbiz.qpic.cn/mmbiz_jpg/YeUmRxGrEBaIPoss68bxNNVaq1ok734WwXTfT3t8LmoWX7MhAQh4ZFRXpTibXwpnc3A61ibuk6jIFZd7pZN7ZFVQ/640?wx_fmt=jpeg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1)

**▋****3. 管道的读写行为**

a. 管道的缓冲区大小固定为4k,所以如果管道内数据已经写满,则无法再写入数据,进程的write调用将阻塞,直到有足够的空间再写入数据;

b. 管道的读动作比写动作要快,数据一旦被读走了,管道将释放相应的空间,以便后续数据的写入。当所有的数据都读完之后,进程的read()调用将阻塞,直到有数据再次写入。

**▋****4. 例程**

**父子间通信:**

```

1#include

2#include

3#include

4#include

5

6int main()

7{

8    int fd[2];

9    pid_t pid;

10    char buf[1024];

11    char *data = "hello world!";

12

13    /* 创建管道 */

14    if (pipe(fd) == -1) {

15        printf("ERROR: pipe create failed!\n");

16        return -1;

17    }

18

19    pid = fork();

20    if (pid == 0) {

21        /* 子进程 */

22        close(fd[1]);   // 子进程读取数据,关闭写端

23        read(fd[0], buf, sizeof(buf));  // 从管道读数据

24        printf("child process read: %s\n", buf);

25        close(fd[0]);

26    } else if (pid > 0) {

27        /* 父进程 */

28        close(fd[0]);   //父进程写数据,关闭读端

29        write(fd[1], data, strlen(data));   // 向管道写数据

30        printf("parent process write: %s\n", data);

31        close(fd[1]);

32    }

33

34    return 0;

35}

```

**兄弟间通信:**

```

1#include

2#include

3#include

4#include

5#include

6

7int main ()

8{

9    int fd[2];

10    int i = 0;

11    pid_t pid;

12    char buf[1024];

13    char *data = "hello world!";

14

15    /* 创建管道 */

16    if (pipe(fd) == -1) {

17        printf("ERROR: pipe create failed!\n");

18        return -1;

19    }

20

21    for (i = 0; i < 2; i++) {

22        pid = fork();

23        if (pid == -1) {

24            printf("ERROR: fork error!\n");

25            return -1;

26        } else if (pid == 0) {

27            break;

28        }

29    }

30

31    /* 通过i来判断创建的子进程及父进程 */

32    if (i == 0) {

33        /* 第一个子进程,兄进程 */

34        close(fd[0]);   // 兄进程向弟进程写数据,关闭读端

35        write(fd[1], data, strlen(data));

36        printf("elder brother send: %s\n", data);

37        close(fd[1]);

38    } else if (i == 1) {

39        /* 第二个子进程,弟进程 */

40        close(fd[1]);

41        read(fd[0], buf, sizeof(buf));

42        printf("younger brother receive: %s\n", buf);

43        close(fd[0]);

44    } else {

45        /* 父进程 */

46        close(fd[0]);

47        close(fd[1]);

48        for (i = 0; i < 2; i++) {

49            wait(NULL);

50        }

51    }

52

53    return 0;

54}

```

更多精彩内容,请关注公众号**良许Linux**,公众内回复**1024**可免费获得5T技术资料,包括:**Linux,C/C++,Python,树莓派,嵌入式,Java,人工智能**,等等。公众号内回复**进群**,邀请您进高手如云技术交流群。

![img](http://pbe9kvqil.bkt.clouddn.com/FmsDX2j5rcQ7DjY8p-KYTN7m5uNu)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值