管道

管道是unix ipc的最古老形式,是一种在内存中的特殊文件,只能在具有公共祖先的进程之间使用(即父子进程,兄弟进程)。

管道由pipe函数创建

#include <unistd.h>

int pipe(int fd[])

fd[1]写,fd[0]读。

单个进程的管道几乎没有任何用处,通常,调用pipe的进程接着调用fork,这样就创建了父子进程间的管道。

#include <unistd.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h> int main()
{
int fd[];
char buf[];
pid_t pid;
pipe(fd);
pid = fork();
if(pid>)
{//父进程
printf("Father thread\n");
char s[]="Hello\n";
write(fd[],s,sizeof(s));
close(fd[]);
close(fd[]);
}
else if(pid==)
{
printf("Child Thread\n");
read(fd[],buf,sizeof(buf));
printf("%s\n",buf);
close(fd[]);
close(fd[]);
}
waitpid(pid,NULL,);//等待子进程结束
return ;
}

输出结果:

Father thread
Child Thread
Hello

当管道的一端关闭时:

  当读一个写端关闭的管道时,则认为已经读到了数据的末尾,读函数返回的读出字节数为0;

  当写一个读端关闭的管道时,向管道中写入数据的进程将收到内核传来的SIFPIPE信号,应用程序可以处理该信号,也可以忽略(默认动作则            是应用程序终止)。

从管道中读取数据:

当管道的写端存在时,如果请求的字节数目大于PIPE_BUF,则返回管道中现有的数据字节数,如果请求的字节数目不大于PIPE_BUF,则返回管道中现有数据字节数(此时,管道中数据量小于请求的数据量);或者返回请求的字节数(此时,管道中数据量不小于请求的数据量)。注:PIPE_BUF在include/linux/limits.h中定义。

向管道中写入数据:

向管道中写入数据时,linux将不保证写入的原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。如果读进程不读走管道缓冲区中的数据,那么写操作将一直阻塞。

管道因为没有名字所以只能用于具有亲缘关系的进程,而有名管道(FIFO)则克服了这个限制。

FIFO

创建函数如下

 #include <sys/types.h>
#include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode);

第一个参数是一个普通的路径名,即为FIFO的名字。第二个参数设置权限,跟创建普通文件一样。

FIFO的读写也像普通文件一样,不过需要读写端都打开,具体规则如下:

当打开(open)时:

若没有设置O_NONBLOCK,只读open要阻塞到其它进程为写而打开FIFO。类似地,只写open要阻塞到其它进程为读而打开FIFO。

如果设置了O_NONBLOCK,则只读open立即返回,若没有其它进程为写而打开FIFO,则返回-1。

用FIFO模拟生产者消费者问题:

fifo2.cpp:

#include<iostream>
#include<unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<limits.h>
#include<stdio.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> #define FIFO "/tmp/myfifo"
#define BUF_SIZE PIPE_BUF
#define SEND_MAX (1024*1024*10)
using namespace std; int main()
{
int pid,fifo_fd;
int send_num;
char *buf[BUF_SIZE+];
if(- == access(FIFO,F_OK))
{
int res = mkfifo(FIFO,);
if(res != )
{
fprintf(stderr,"can't create fifo in %s",FIFO);
exit(EXIT_FAILURE);
}
} fifo_fd = open(FIFO,O_WRONLY);
printf("process %d open fifo %d\r\n",getpid(),fifo_fd);
if(fifo_fd == -)
exit(EXIT_FAILURE);
int res;
while(send_num<SEND_MAX)
{
res = write(fifo_fd,buf,BUF_SIZE);
if(res == -)
{
cout<<"write fifo error"<<endl;
exit(EXIT_FAILURE);
}
send_num += res;
}
return ;
}

fifo3.cpp

#include<iostream>
#include<unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include<limits.h>
#include<stdio.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> #define FIFO "/tmp/myfifo"
#define BUF_SIZE PIPE_BUF
#define SEND_MAX (1024*1024*10)
using namespace std; int main()
{
int fifo_fd;
int res;
char buffer[BUF_SIZE+];
int read_num = ; fifo_fd = open(FIFO,O_RDONLY);
printf("process %d open FIFO %d\r\n",getpid(),fifo_fd);
if(fifo_fd == -)
exit(EXIT_FAILURE);
do{
res = read(fifo_fd,buffer,BUF_SIZE);
read_num += res;
}while(res>);
close(fifo_fd);
return ;
}

结果如下:

可见读进程运行0.013s就读取了10m的数据,FIFO的效率还是很高的。

linux IPC总结——管道的更多相关文章

  1. Linux IPC之管道通信

    2017-04-07 管道通信在linux中使用较为频繁的进程通信机制.基于unix一切皆文件的传统,管道也是一种文件.所以可以使用一般的VFS接口对管道进行读写操作,如read.write.具体管道 ...

  2. Linux IPC实践(1) -- 概述

    进程的同步与互斥 进程同步: 多个进程需要相互配合共同完成一项任务. 进程互斥: 由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥;系统中某些 ...

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

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

  4. linux ipc/its

    linux进程间双向消息队列 server.c #include <stdio.h> #include <stdlib.h> #include <string.h> ...

  5. Linux下的管道命令有这些:

    Linux下的管道命令有这些: 选取命令:cat grep 排序命令:sort wc uniq 双向重定向:tee 字符转换命令: tr, col, join, paste, expand 切割命令: ...

  6. linux进程的管道通信

    linux进程的管道通信 要求 编程实现进程的管道通信,掌握管道通信的同步和互斥机制. 相关函数 pipe管道 指用于连接一个读进程和一个写进程以实现他们之间通信的一个共享文件,又名pipe文件.向管 ...

  7. Linux IPC之共享内存C 事例

    Linux IPC之共享内存 标签: linuxrandomnull工作 2011-08-25 11:52 4123人阅读 评论(0) 收藏 举报  分类: Linux(3)  读书札记(3)  版权 ...

  8. 【Linux】【专项突破】Linux重定向与管道

    [专项突破]Linux重定向与管道 This article is written by Xrilang(Chinese Name:萌狼蓝天) If you want find me ,You can ...

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

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

随机推荐

  1. 24种设计模式--观察者模式【Observer Pattern】

     <孙子兵法>有云: “知彼知己,百战不殆:不知彼而知己,一胜一负:不知彼,不知己,每战必殆”,那怎么才能知己知彼呢?知己是很容易的,自己的军队嘛,很容易知道,那怎么知彼呢?安插间谍是很好 ...

  2. AJAX 简单上手

    AJAX简介 没有AJAX会怎么样?普通的ASP.Net每次执行服务端方法的时候都要刷新当前页面,如实现显示服务器的时间每次都要刷新页面的坏处:页面刷新打断用户操作.速度慢.增加服务器的流量压力.如果 ...

  3. windows平台 culture name 详细列表

    点击打开链接http://msdn.microsoft.com/zh-cn/goglobal/bb896001.aspx LCID Culture Identifier Culture Name Lo ...

  4. Linux Shell脚本之自动修改IP

    作为一名Linux SA,日常运维中很多地方都会用到脚本,而服务器的ip一般采用静态ip或者MAC绑定,当然后者比较操作起来相对繁琐,而前者我们可以设置主机名.ip信息.网关等配置.修改成特定的主机名 ...

  5. 网站开发常用jQuery插件总结(14)图片修剪插件Jcrop

    一.插件功能 用于对图片进行修剪.但是在使用Jcrop时,还需要配合服务器端开发语言(如asp.net,php等)使用. 二.官方地址 http://deepliquid.com/content/Jc ...

  6. BOM 子对象,history,location,screen

    history:包括浏览器访问过的 url 属性:返回浏览器访问过的历史记录数 方法:back(); forward(); go(number) location:包含当前 url 的相关信息 属性: ...

  7. JavaScript实现url地址自动检测并添加URL链接示例代码

    写一个简单的聊天系统,发出Htpp的Url实现跳转加上a标签,下面是具体的实现,感兴趣的朋友不要错过 背景:写一个简单的聊天系统,发出Htpp的Url实现跳转加上a标签.  实现代码: 复制代码代码如 ...

  8. PHP PhantomJs中文文档(翻译)

    介绍 PHP PhantomJS 是一个灵活的 PHP 库加载页面通过 PhantomJS 无头浏览器并将返回页面响应.这是方便于需要JavaScript的支持,同时还支持截屏测试网站.功能列表通过 ...

  9. PHP — php精粹-编写高效的php代码 --- API

    1.数据格式 (1)json 示例代码: $jsonData = '[{"title":"The Magic Flute","time":1 ...

  10. 全面理解.htaccess语法中RewriteCond和RewriteRule意义

    RewriteCond的语法 RewriteCond TestString CondPattern [Flags]其中的TestString是指一个文本格式的条件,例子中用的是环境变量名HTTP_HO ...