匿名管道pipe

函数原型:

#include <unistd.h>
int pipe(int fildes[2]);

参数说明

fildes是我们传入的数组,也是一个传出参数。fildes[0]是读端,fildes[1]是写端。

返回值

  • 成功调用返回0。
  • 失败调用返回-1且设置errno.

实例

现在实现一个用父进程读,子进程写的管道例子。

int main(int argc, char const *argv[])
{
int pipefd[2];
pipe(pipefd);
pid_t pid = fork();
if (pid == 0)
{
//子进程写
//关闭读
close(pipefd[0]);
write(pipefd[1], "hello fuck!", 15);
sleep(1);
}
else if (pid > 0)
{
//关闭写
close(pipefd[1]);
char buf[16] = {0};
read(pipefd[0], buf, sizeof(buf));
printf("%s\n", buf);
}
return 0;
}

在这个程序执行之后,父进程会读取到子进程所写的数据。在这个简单的例子中看不到什么坑点。

坑点

在亲缘进程中,我们使用管道要注意以下几点。就拿父子进程作为例子:

当前情况是,双方都掌控有读写端,都可以操作。

fork之后,共享管道的读写端。我们一方读一方写,最好要自己指定方向,使数据沿着固定的方向流动。如:

我们这样就指定了子进程来写,父进程来读。也就是说,我们仅仅只需要在代码上加上两个Close就可以完成这个功能:close父进程的写端,close子进程的读端。

如果我们不这样会发生什么?

坑点总结

  • 写进程:

    • 读端全部关闭: 在写进程中,如果内核发现读端全部关闭,内核会认为没有人会来读数据,因此杀死写进程,通过发出的SIGPIPE。
    • 读端并未全部关闭: 在写进程中,如果内核发现读端并未全部关闭,会写入数据直到管道满,write会阻塞,等待数据被读取,有地方可写会再写。
  • 读进程:
    • 写端全部关闭: 在读进程中,写端全部关闭,会读取完管道中的数据,然后返回0,表示读到末尾了。和文件读取一致。
    • 写端并未全部关闭: 在读进程中,写端并未全部关闭,如果管道有数据就会读取,没有数据就会阻塞等待写端的写入。

其中特别要注意,写端没有全关闭的时候并且无数据的时候,读端会阻塞等待写。

Note

  • 数据不能反复读取,读了就会被取走。
  • 半双工。
  • 有亲缘关系进程间使用。
  • 可以通过ulimit -a指令查看各种块的限制大小。其中pipe size就是管道的大小。

FIFO有名管道

此管道突破了匿名管道只能亲缘间通信的限制。

可以用命令直接创建一个有名管道:

mkfifo myfifo

就可以看到一个myfifo管道了。Linux下一切皆文件,打开这个管道和打开文件一样,用open函数即可。

下面写了一个读程序和写程序,可以参考:

//读进程,读了就会被取走,可同时执行两次看结果
int main(int argc, char const *argv[])
{
int fd = open("myfifo", O_RDONLY);
while (1)
{
char buf[128] = {0};
int ret = read(fd, buf, sizeof(buf)); //如果写端被关闭,读端返回0,就是读到末尾了。
if (ret) printf("%s\n", buf);
else break;
}
return 0;
}

写程序如下:

//写进程。
int main(int argc, char const *argv[])
{
int fd = open("myfifo", O_WRONLY);
int num = 1;
while (1)
{
char buf[128] = {0};
sprintf(buf, "read data:%04d", num++);
write(fd, buf, strlen(buf));
sleep(1);
}
return 0;
}

和普通文件操作并无区别。

Note

假设我们先执行读程序,还没执行写程序时,会阻塞,直到写端被打开。

同理,我们先执行写程序,还没执行读程序时,也会阻塞,知道读端被打开。

以上告诉我们,fifo必须两端都打开的时候才能工作,否则阻塞。

进程间通信之管道--pipe和fifo使用的更多相关文章

  1. 【Linux 应用编程】进程管理 - 进程间通信IPC之管道 pipe 和 FIFO

    IPC(InterProcess Communication,进程间通信)是进程中的重要概念.Linux 进程之间常用的通信方式有: 文件:简单,低效,需要代码控制同步 管道:使用简单,默认阻塞 匿名 ...

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

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

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

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

  4. 【IPC第二个进程间通信】管道Pipe

    IPC进程间通信+管道Pipe                IPC(Inter-Process Communication,进程间通信).         管道用于进程间共享数据,事实上质是共享内存 ...

  5. IPC 进程间通信方式——管道

    进程间通信概述 数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几兆字节之间 共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到. 通知时间: ...

  6. linux中管道(pipe)一谈

    /*********************************************** 管道(pipe)是Linux上进程间通信的一种方式,其是半双工(数据流只能在一个方向上流动(还需要经过 ...

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

    我们先来说说进程间通信(IPC)的一般目的,大概有数据传输.共享数据.通知事件.资源共享和进程控制等.但是我们知道,对于每一个进程来说这个进程看到属于它的一块内存资源,这块资源是它所独占的,所以进程之 ...

  8. Unix/Linux进程间通信(二):匿名管道、有名管道 pipe()、mkfifo()

    1. 管道概述及相关API应用 1.1 管道相关的关键概念 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: 管道是半双工的,数据只能向一个方向流动:需要双方通信时,需要建立起两个管 ...

  9. 进程间通信和同步:pipe、FIFO、消息队列、信号量、共享内存、信号

    一.半双工管道(pipe) 关于管道详细介绍可参考http://www.cnblogs.com/nufangrensheng/p/3560130.html. 1.管道实现父子进程间通信实例: /* p ...

随机推荐

  1. join函数详解

    定义:join() 方法用于把数组中的所有元素放入一个字符串. 语法 : ArrayObject.join(separator)   separator 可选.指定要使用的分隔符.如果省略该参数,则使 ...

  2. JXOI 2018滚粗记

    --Update5.2 成绩出了,见后文 听说省选VAN写游记是传统,本蒟蒻也来发一篇吧. DAY 0 本来以为省选不在JKFZ举行的结果又是在JKFZ,本校作战感觉终究会是好一些吧,和jyh一起向教 ...

  3. Qtspim和MIPS的坑

    Qtspim和MIPS的坑 数组要么用空格隔开,要么逗号之后再加一个空格 乘法的结果保存在(HI,LO)寄存器中,但是不能直接通过Move得到,必须使用mfhi 和mflo指令 用户输入的数组最后一个 ...

  4. VS2008提示无法打开包括文件:“afxcontrolbars.h”解决办法

    主要造成这个问题的主要原因是,在打了SP1的VS2008下创建的项目放在没有打SP1的VS2008下就会报错   解决办法: 一.给VS2008打上SP1补丁即可      此方法比较彻底,但是安装较 ...

  5. 5.Hibernate 核心开发接口

    一.Configuration(AnnotationConfiguration) 作用:进行配置信息的管理 目标:用来产生SessionFactory 可以在configure 方法中指定hibern ...

  6. linux的top下buffer与cache的区别、free命令内存解释

    buffer:    缓冲区,一个用于存储速度不同步的设备或优先级不同的设备之间传输数据 的区域.通过缓冲区,可以使进程之间的相互等待变少,从而使从速度慢的设备读入数据 时,速度快的设备的操作进程不发 ...

  7. 写Java也得了解CPU–CPU缓存

    CPU,一般认为写C/C++的才需要了解,写高级语言的(Java/C#/pathon…)并不需要了解那么底层的东西.我一开始也是这么想的,但直到碰到LMAX的Disruptor,以及马丁的博文,才发现 ...

  8. Linux下Mysql 不能访问新数据文件夹问题

    新挂载的盘,打算将数据文件夹配置到 /data/mysql,却无法启动mysqld. 除了将目录授权给mysql用户和组以外 chown -R mysql:mysql /data/mysql 太需要将 ...

  9. python常用模块:pickle、shelve、json、xml、configparser

    今日内容主要有: 一.pickle模块二.shelve模块三.json模块四.json练习五.xml模块 六.xml练习七.configparser模块 一.pickle模块 #pickle是一个用来 ...

  10. python常有模块:模块、引入语法、两种执行方式、模块搜索顺序

    今天主要讲了以下几点:一.模块三问.定义及分类二.import和from的语法三.文件的两种执行方式及搜索顺序四.内置函数 一.模块.import和from的语法 1.什么是模块   模块是一堆功能函 ...