进程间通信-无名管道

无名管道是单工的工作方式,即进程要么只能读管道,要么只能写管道。父子进程虽然都拥有管道的读端和写端,但是只能使用其中一个(例如,可以约定父进程读管道,而子进程写管道)。这样就应该把不使用的读端 或写端文件描述符关闭 

进程间通信-无名管道_第1张图片

进程间通信-无名管道_第2张图片  

int fd[2] 亲缘
进程间通信-无名管道_第3张图片
创建无名管道的函数
#include
int pipe(int pipefd[2]);
参数是个数组,这个函数的操作返回管道( 开口 ) 两边的文件描述符(管道也是文件)。
可拿到管道两端的文件描述符。成功返回 0 ,失败返回-1。
例如:如果将父进程的读端 fd[0] 和子进程的写端 fd[1] 关闭。此时,父子进程之间就建立了一条“父进程。写入子进程读取”的通道。同样,也可以关闭父进程的 fd[1] 和子进程的 fd[0] ,这样就可以建立一条“父进程读取子进程写入”的通道。另外,父进程也可以创建 多个子进程,各个子进程都继承了管道的 fd[0] fd[1] , 这样就建立子进程之间的数据通道。
这里所说的管道主要指无名管道,它具有如下特点:
1、只能用于具有亲缘关系的进程之间的通信;
2、半双工的通信模式,具有固定的读端和写端;
3、管道可以看成是一种特殊的文件,对于它的读写可以使用文件 IO read write 函数;
4、管道是基于文件描述符的通信方式。当一个管道建立时,它会创建两个文件描述符 fd[0] fd[1] 。其中 fd[0] 固定用于读管道,而 fd[1] 固定用于写管道。 构成了一个半双工的通道。
进程间通信-无名管道_第4张图片
当管道中无数据时,读操作会阻塞。向管道中写入数据时,linux 将不保证写入的原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。如果读进程不读走管道缓冲区中的数据,那么当缓冲区满的时候写操作将会一直阻塞。
只有在管道的读端存在时,向管道中写入数据才有意义。否则,向管道中写入数据的进程将收到内核传来的。SIFPIPE 信号 ( 通常 Broken pipe 错误 )
特殊文件 , 例如 lseek 不能用来定位。

 进程间通信-无名管道_第5张图片

示例:

#include 
#include 
#include 
#include 
#define MAX 99999
//测试无名管道大小
int main(int argc, char const *argv[])
{
   int fd[2], size = 1;
   char buf[MAX];
   pipe(fd);
   while (1) {
     //当写入字节大于管道大小发生阻塞
     write(fd[1], "w", 1);
     printf("pipe size : %d\n", size++);
   }
   
   return 0;
}

/*
pipe size : 65536
开始阻塞
*/

你可能感兴趣的:(linux,运维,服务器)