linux管道特点,Linux中的管道pipe----管道的四种情况和特点

Linux中的管道pipe----管道的四种情况和特点

Linux中的管道pipe----管道的四种情况和特点

管道(pipe)----是用来支持两个或多个进程间进行进程间通信(IPC)进程间通信(IPC)----每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到。所以进程之间要交换数据必须通过内核。不同进程看到的公共资源是由操作系统(OS)提供的。管道(pipe)函数原型为: int pipe(int pipefd[2]) pipefd[2]为输出型参数,是一个数组,存放打开的两个文件描述符。一般情况下,文件描述符0、1、2为标准输入输出错误,pipefd[0]打开文件描述符3,pipefd[1]打开文件描述符4。0、1下标分别对应管道的读端和写端。管道的特点:(1)管道适用于单向通信,防止用户误操作;(2)管道目前只用于具有血缘关系的进程,常用于父子进程;(3)管道的生命周期是:随进程,管道是文件,在进程退出时文件销毁,管道也销毁;(4)管道是基于字节流的通信方式;(5)管道内部已经实现了同步,具有数据一致性;下面是在Linux下的一个管道程序,我们创建一个进程,让子进程写,父进程读。父子进程同时有读端和写端,所以需要各自关闭一端。1 #include

2 #include

3 #include

4 #include

5 int main()

6 {

7 int fds[2];

8 if(pipe(fds)<0)

9 {

10 perror("pipe");

11 return 1;

12 }

13 printf("fds0:%d,fds1:%d\n",fds[0],fds[1]);

14

15 pid_t id=fork();

16 if(id==0)

17 {

18 close(fds[0]); //子进程关闭读端

19 const char* child="hello father,i am child!";

20 int i=0;

21 while(i<10) //只写入10次数据

22 {

23 sleep(1);

24 printf("child run...!,%d\n",i);

25 write(fds[1],child,strlen(child));

26 i++;

27 }

28 exit(0);

29 }

30 else

31 {

32 close(fds[1]); //父进程关闭写端

33 char buf[1024];

34 while(1)

35 {

36 ssize_t s=read(fds[0],buf,sizeof(buf)-1); //读成功后进行打印

37 if(s>0)

38 {

39 buf[s]=0;

40 printf("father recv:%s\n",buf);

41 }

42 }

43 pid_t ret=waitpid(id,NULL,0);

44 if(ret>0)

45 {

46 printf("waitpid success!\n");

47 }

48 }

49 }

c34c68e951ced8306788a5f1ddcecf86.png

管道有四种情况:

1、读方不关闭读端,但是不读,写方一直在写----子进程会一直写,直到写满缓冲区

1 #include

2 #include

3 #include

4 #include

5 int main()

6 {

7 int fds[2];

8 if(pipe(fds)<0)

9 {

10 perror("pipe");

11 return 1;

12 }

13 printf("fds0:%d,fds1:%d\n",fds[0],fds[1]);

14

15 pid_t id=fork();

16 if(id==0)

17 {

18 close(fds[0]);

19 const char* child="hello father,i am child!";

20 int i=0;

21 while(1) //子进程一直写

22 // while(i<10)

23 {

24 // sleep(1);

25 printf("child run...!,%d\n",i);

26 write(fds[1],child,strlen(child));

27 i++;

28 }

29 exit(0);

30 }

31 else

32 {

33 close(fds[1]);

34 char buf[1024];

35 sleep(100000); //父进程不读,进行睡眠

36 while(1)

37 {

38 ssize_t s=read(fds[0],buf,sizeof(buf)-1);

39 if(s>0)

40 {

41 buf[s]=0;

42 printf("father recv:%s\n",buf);

43 }

44 }

45 pid_t ret=waitpid(id,NULL,0);

46 if(ret>0)

47 {

48 printf("waitpid success!\n");

49 }

50 }

51 }

c159b02ad2c997af9d17f61f722b60f8.png

2、读方一直读,写方不写,没有关闭写端----父进程一直在等待子进程写入

1 #include

2 #include

3 #include

4 #include

5 int main()

6 {

7 int fds[2];

8 if(pipe(fds)<0)

9 {

10 perror("pipe");

11 return 1;

12 }

13 printf("fds0:%d,fds1:%d\n",fds[0],fds[1]);

14

15 pid_t id=fork();

16 if(id==0)

17 {

18 close(fds[0]);

19 const char* child="hello father,i am child!";

20 int i=0;

21 sleep(10000); //写方不写

22 while(1)

23 // while(i<10)

24 {

25 // sleep(1);

26 printf("child run...!,%d\n",i);

27 write(fds[1],child,strlen(child));

28 i++;

29 }

30 exit(0);

31 }

32 else

33 {

34 close(fds[1]);

35 char buf[1024];

36 while(1)

37 {

38 ssize_t s=read(fds[0],buf,sizeof(buf)-1);

39 if(s>0)

40 {

41 buf[s]=0;

42 printf("father recv:%s\n",buf);

43 }

44 }

45 pid_t ret=waitpid(id,NULL,0);

46 if(ret>0)

47 {

48 printf("waitpid success!\n");

49 }

50 }

51 }

4b4df2aa3570e0fa3c4d76d8671ba8ac.png

3、写方写了一些不写了,关闭了写端,读方读完剩余的数据后,read返回0,就像读到了文件结尾一样

16 if(id==0)

17 {

18 close(fds[0]);

19 const char* child="hello father,i am child!";

20 int i=0;

21 // sleep(10000);

22 while(1)

23 {

24 sleep(1);

25 printf("child run...!,%d\n",i);

26 write(fds[1],child,strlen(child));

27 i++;

28 if(i>5) //写方写入5次之后关闭写端

29 {

30 close(fds[1]);

31 break;

32 }

33 }

34 exit(0); 35     }

36     else

37     {//father->read

38         close(fds[1]);

39         char buf[1024];

40         int count=0;

41         while(1)

42         {

43             ssize_t s=read(fds[0],buf,sizeof(buf)-1);

44             if(s>0)

45                 {

46                     buf[s]=0;

47                     printf("father recv:%s\n",buf);

48                 }

49             if(s==0) //读失败

50             {

51                 printf("no write,code:%d\n",s);

52             }

53         }

54         int status=0; 55         pid_t ret=waitpid(id,&status,0); 56         if(ret>0) 57         { 58             printf("waitpid success!,sig:%d,exitCode:%d\n",status&0xff,(status>>8)&0xff); 59

} 60     } 61 }

88c6eb43f491971a5621f22ae031febb.png

4、写方一直在写,读方读了一些后直接退出,关闭读端----读方只读了一些后退出,waitpid收到异常信号13

36     else

37     {//father->read

38         close(fds[1]);

39         char buf[1024];

40         int count=0;

41         while(1)

42         {

43             ssize_t s=read(fds[0],buf,sizeof(buf)-1);

44             if(s>0)

45                 {

46                     buf[s]=0;

47                     printf("father recv:%s\n",buf);

48                 }

49             count++;

50             if(count>5) //读方读了五次数据后关闭读端,直接退出

51             {

52                 close(fds[0]);

53                 break;

54             }

55         } 56         int status=0;

57         pid_t ret=waitpid(id,&status,0);

58         if(ret>0)

59         {

60             printf("waitpid success!,sig:%d,exitCode:%d\n",status&0xff,(status>>8)&0xff);

61         }

62     }

63 }

95a3c65231001f1f3a6dc1a7d4cdcbaf.png

7f6fa2081079349f81965c9f1c260da4.png

Linux中的管道pipe----管道的四种情况和特点相关教程

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值