管道

只能用于具有亲缘关系的进程之间通信是一个半双工的通信模式,

具有固定的写读端和写端,管道可以看成一种特殊的文件,对它可以使用普通的read、write等操作

管道的创建:

#include <unistd.h>

int pipe(int fd[2])

该函数创建的管道的两端处于一个进程中间,在实际应用中没有太大意义,因此,一个进程在由pipe()创建管道后,一般再fork一个子进程,

然后通过管道实现父子进程间的通信(因此也不难推出,只要两个进程中存在亲缘关系,这里的亲缘关系指的是具有共同的祖先,都可以采用管道方式来进行通信)。

管道两端可分别用描述字fd[0]以及fd[1]来描述,需要注意的是,管道的两端是固定了任务的。

即一端只能用于读,由描述字fd[0]表示,称其为管道读端;另一端则只能用于写,由描述字fd[1]来表示,称其为管道写端。

如果试图从管道写端读取数据,或者向管道读端写入数据都将导致错误发生。一般文件的I/O函数都可以用于管道,如close、read、write等等。

从管道中读取数据: 如果管道的写端不存在,则认为已经读到了数据的末尾,读函数返回的读出字节数为0;

当管道的写端存在时,如果请求的字节数目大于PIPE_BUF,则返回管道中现有的数据字节数,

如果请求的字节数目不大于PIPE_BUF,则返回管道中现有数据字节数(此时,管道中数据量小于请求的数据量);

或者返回请求的字节数(此时,管道中数据量不小于请求的数据量)。

注:(PIPE_BUF在include/linux/limits.h中定义,不同的内核版本可能会有所不同。Posix.1要求PIPE_BUF至少为512字节,有的是4096)。

向管道中写入数据时,linux将不保证写入的原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。

如果读进程不读走管道缓冲区中的数据,那么写操作将一直阻塞。 注:只有在管道的读端存在时,向管道中写入数据才有意义。否则,默认动作则是应用程序终止.

列子:

无名管道

1 #include<unistd.h>
2 #include<sys/types.h>
3 #include<errno.h>
4 #include<stdio.h>
5 #include<stdlib.h>
6
7 int main()
8 {
9       int pipe_fd[2];
10       pid_t pid;
11       char buf_r[100];
12       char* p_wbuf = NULL ;
13       int r_num = 0 ;
14     memset(buf_r , 0 ,sizeof(buf_r));
15       if(pipe(pipe_fd) < 0) //返回0表示创建失败
16        {
17            printf("pipe create error \n");
18            return -1;
19        }
20        if( (pid=fork()) == 0) //子进程中 fork()创建子进程会继承父进程的所有,包括管道啦。
21        {
22            printf("\n ");
23            close(pipe_fd[1]);//关闭写管道
24            sleep(1);
25            if((r_num = read(pipe_fd[0],buf_r,100)) >0) // 返回读写数
26              {
27                printf("%d \n numbers read from the pipe is %s\n",r_num ,buf_r);

close(pipe_fd[0]);
29                exit(0);
30              }
31        }
32        else if(pid > 0) //父进程中
33        {
34          close(pipe_fd[0]);
35          if(write(pipe_fd[1], "Hello " , 5) != -1)
36          printf("parent write1 success!\n");
37          if(write(pipe_fd[1]," Pipe" , 5) != -1)
38          printf("parent write2 success!\n");
39          close(pipe_fd[1]);
40           sleep(1);
41           waitpid(pid ,NULL ,0); //等子进程结束
42           exit(0);
43        }
44      return 0;
45 }

linux进程间通信--无名管道的更多相关文章

  1. Linux 进程间通信 无名管道(pipe)

    无名管道: 1)只能用于具有亲缘关系的进程之间的通信(无名管道是某一个进程创建的,不像普通文件有路径,在文件系统中是不可见的,其他进程要想打开,只能通过继承的方式去打开) 2)半双工的通信模式,具有固 ...

  2. Linux进程间通信之管道

    1,进程间通信 (IPC ) Inter-Process Communication 比较好理解概念的就是进程间通信就是在不同进程之间传播或交换信息. 2,linux下IPC机制的分类:管道.信号.共 ...

  3. Linux 进程间通信(二) 管道

    Linux 进程间通信-管道 进程是一个独立的资源分配单位,不同进程之间的资源是相互独立的,没有关联,不能在一个进程中直接访问另一个进程中的资源.但是,进程不是孤立的,不同的进程之间需要信息的交换以及 ...

  4. Linux -- 进程间通信之管道

    管道是 Linux 里的一种文件类型,同时也是 Linux 系统下进程间通信的一种方式   创建一个管道文件有两种方式:  Shell 下命令 mkfifo + filename,即创建一个有名管道 ...

  5. linux进程间通信--有名管道

    有名管道 只有当一个库函数失败时,errno才会被设置.当函数成功运行时,errno的值不会被修改.这意味着我们不能通过测试errno的值来判断是否有错误存在.反之,只有当被调用的函数提示有错误发生时 ...

  6. linux之无名管道

    1.查看命令: man 2 pipe 2.头文件:#include <unistd.h> 3.函数原型: int pipe(int pipefd[2]); a.pipefd[2] :无名管 ...

  7. Linux 进程间通信之管道(pipe),(fifo)

     无名管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信: 定义函数: int pipe(int f ...

  8. Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)

    整理自网络 Unix IPC包括:管道(pipe).命名管道(FIFO)与信号(Signal) 管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道 ...

  9. Linux 进程间通信 有名管道(fifo)

    有名管道特点: 1)无名管道只能用于具有亲缘关系的进程之间,这就限制了无名管道的使用范围 2)有名管道可以使互不相关的两个进程互相通信. 3)有名管道可以通过路径名来指出,并且在文件系统中可见,但内容 ...

随机推荐

  1. nginx + lua 构建网站防护waf(一)

    最近在帮朋友维护一个站点.这个站点是一个Php网站.坑爹的是用IIS做代理.出了无数问题之后忍无可忍,于是要我帮他切换到nginx上面,前期被不断的扫描和CC.最后找到了waf这样一个解决方案缓解一下 ...

  2. html的框架

  3. ip头、tcp头、udp头详解及定义,结合Wireshark抓包看实际情况

    公司的同事们在分析网页加载慢的问题,忽然使用到了Wireshark工具,我就像发现新大陆一样好奇,赶紧看了看,顺便复习了一下相关协议.上学时学的忘的差不多了,汗颜啊! 报文封装整体结构 mac帧头定义 ...

  4. SecureCRT 终端仿真程序 v7.0.0.326 中文绿色便携破解版

    http://wd.jb51.net:81/201205/tools/SecureCRT_jb51.rar Secure CRT是一款支持 SSH2.SSH1.Telnet.Telnet/SSH.Re ...

  5. hdu4486 Pen Counts(水题)

    Pen Counts Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. ListBox获取行字符串

    ListBox获取行字符串 关键点 获取ListBox第1行的字符串 获取ListBox第2行的字符串 获取ListBox第n行的字符串 CListBox::GetText int GetText( ...

  7. PHP获取客户端和服务器IP地址

    /** * 获取客户端IP地址 * @return string */ function get_client_ip() { if(getenv('HTTP_CLIENT_IP')){ $client ...

  8. 使用startCoroutine制定倒计时

    使用startCoroutine制定倒计时 using UnityEngine; using System.Collections; public class TimerCoroutine : Mon ...

  9. insert例子

    11.20 使用insert代替下标操作. #include<iostream> #include<map> #include<string> #include&l ...

  10. C#扫盲之:静态成员、静态方法、静态类、实例成员及区别

    文章目录 1.静态成员.实例成员 2.静态类 3.类的静态成员和非静态成员区别 --------------------------------------分割线------------------- ...