进程间通信之无名管道和有名管道

编程入门 行业动态 更新时间:2024-10-24 12:29:09

进程间通信之无名<a href=https://www.elefans.com/category/jswz/34/1771259.html style=管道和有名管道"/>

进程间通信之无名管道和有名管道

无名管道和有名管道

    • 一、无名管道
      • 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;/

更多推荐

进程间通信之无名管道和有名管道

本文发布于:2024-02-27 16:58:50,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1707454.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:管道   有名   进程   通信

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!