管道和有名管道"/>
进程间通信之无名管道和有名管道
无名管道和有名管道
- 一、无名管道
- 1.什么是无名管道
- 2.局限性
- 3.pipe()函数
- 4.流程图
- 5.例程
- 二、有名管道
- 1.什么是有名管道
- 2.mkfifo()函数
- 3.流程图
- 4.例程
无名管道(匿名管道)和有名管道(命名管道)是Linux系统内核的特殊文件,用于进程之间的通信。
一、无名管道
1.什么是无名管道
无名管道(匿名管道)的实质是一个内核缓冲区,进程以先进先出(FIFO, First In First Out)的方式从缓冲区存取数据:管道一端的进程顺序地将进程数据写入缓冲区,另一端的进程则顺序地读取数据,该缓冲区可以看做一个循环队列,读和写的位置都是自动增加的,一个数据只能被读一次,读出以后再缓冲区都不复存在了。当缓冲区读空或者写满时,有一定的规则控制相应的读进程或写进程是否进入等待队列,当空的缓冲区有新数据写入或慢的缓冲区有数据读出时,就唤醒等待队列中的进程继续读写。
无名管道相当于一个队列结构,fd[1]为写入端(入队),fd[0]为读出端(出队)。其中信息读出后即删除,再次读取时即为下一个信息。无名管道通过调用pipe()函数创建, 通过操作fd[1]写入信息,操作fd[0]读取信息。只有具有亲缘关系(有共同的祖先进程)的进程间才可以通过此管道进行通信。
2.局限性
这里有两个局限性:
① 管道是半双工的, 我们可以通过建立两个管道来实现全双工。
管道的数据流方向取决于程序员
-
需要写入则进程关闭读取的文件描述符,如果管道的另一端关闭了读的文件描述符,此时写入信息会产生SIGPIPE信号,系统默认程序退出,可以根据自己需求捕捉此信号。
连接建立后,若某一端关闭连接,而另一端仍然向它写数据,第一次写数据后会收到RST响应,此后再写数据,内核将向进程发出SIGPIPE信号,通知进程此连接已经断开。SIGPIPE信号的默认处理是终止程序。
-
需要读取则关闭写入的文件描述符,在管道所有的数据被读取后,read()函数会返回0, 表示文件结束。 数据读取走后,便不在管道中,在没有读取到之前, read()函数会一直阻塞。
② 无名管道只能支持具有亲缘关系的进程间通信, 我们后面可以通过命名管道解决此问题。
3.pipe()函数
#include <unistd.h>int pipe(int pipefd[2]); //成功返回0, 失败返回-1并将返回错误信息errno//pipefd[0]为读端,pipefd[1]为写端
在调用pipe()函数成功后,创建内核缓冲区(也就是管道),不需要手动open()打开,会返回读端pipefd[0]、写端pipefd[1]两个文件描述符,但是需要手动close()关闭。
4.流程图
5.例程
/********************************************************************************** Copyright: (C) 2020 Qiuliang<comeonqiuliang@163>* All rights reserved.** Filename: test_pipe_2.c* Description: This file is test of pipe * * Version: 1.0.0(2020年04月09日)* Author: Qiuliang <comeonqiuliang@163>* ChangeLog: 1, Release initial version on "2020年04月09日 17时40分50秒"* ********************************************************************************/#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>#define WORLD "我是你爸爸!" /* */int g_run = 0;void do_pipe(int signal)
{if(SIGPIPE == signal){printf("管道读端关闭, 一秒后退出。\n");sleep(1);g_run = 1;}
}//读端关闭执行此程序int main(int argc, char *argv[])
{int ppfd[2];int pid = -1;int rv = -1;int i=0;int fork_status;/
更多推荐
进程间通信之无名管道和有名管道
发布评论