linux IPC总结——管道
管道
管道是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总结——管道的更多相关文章
- Linux IPC之管道通信
2017-04-07 管道通信在linux中使用较为频繁的进程通信机制.基于unix一切皆文件的传统,管道也是一种文件.所以可以使用一般的VFS接口对管道进行读写操作,如read.write.具体管道 ...
- Linux IPC实践(1) -- 概述
进程的同步与互斥 进程同步: 多个进程需要相互配合共同完成一项任务. 进程互斥: 由于各进程要求共享资源,而且有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥;系统中某些 ...
- Linux进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)
整理自网络 Unix IPC包括:管道(pipe).命名管道(FIFO)与信号(Signal) 管道(pipe) 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道 ...
- linux ipc/its
linux进程间双向消息队列 server.c #include <stdio.h> #include <stdlib.h> #include <string.h> ...
- Linux下的管道命令有这些:
Linux下的管道命令有这些: 选取命令:cat grep 排序命令:sort wc uniq 双向重定向:tee 字符转换命令: tr, col, join, paste, expand 切割命令: ...
- linux进程的管道通信
linux进程的管道通信 要求 编程实现进程的管道通信,掌握管道通信的同步和互斥机制. 相关函数 pipe管道 指用于连接一个读进程和一个写进程以实现他们之间通信的一个共享文件,又名pipe文件.向管 ...
- Linux IPC之共享内存C 事例
Linux IPC之共享内存 标签: linuxrandomnull工作 2011-08-25 11:52 4123人阅读 评论(0) 收藏 举报 分类: Linux(3) 读书札记(3) 版权 ...
- 【Linux】【专项突破】Linux重定向与管道
[专项突破]Linux重定向与管道 This article is written by Xrilang(Chinese Name:萌狼蓝天) If you want find me ,You can ...
- 【Linux 应用编程】进程管理 - 进程间通信IPC之管道 pipe 和 FIFO
IPC(InterProcess Communication,进程间通信)是进程中的重要概念.Linux 进程之间常用的通信方式有: 文件:简单,低效,需要代码控制同步 管道:使用简单,默认阻塞 匿名 ...
随机推荐
- x264_param_t结构
typedef struct x264_param_t { unsigned int cpu; // CPU 标志位 int i_threads; // 并行编码多帧; 线程数,为0则自动多线程编码 ...
- css中 中文字体(font-family)的标准英文名称
Mac OS的一些: 华文细黑:STHeiti Light [STXihei] 华文黑体:STHeiti 华文楷体:STKaiti 华文宋体:STSong 华文仿宋:STFangsong 儷黑 Pro ...
- Class TBoundlabel not found and so on..
Class TBoundlabel not found when you put a labeledit into a panel of CategoryPanel then you'll found ...
- 炼狱—Bug集中营
关联性 Bug1:在web.config配置了一个配置项,但是却没有在app.config(测试工程)中进行配置: CresteOrder的加密参数为了符合QQ要求增加了一个sessionKey,但是 ...
- PHP中的urlencode和urldecode的理解
平时在工作中经常要写 $xxx = urldecode($_GET['xxx']);的类似代码,大部分的情况都是没有问题的.也能很好的工作. 所以也没有怎么在意.但是突然有一天我想到 $xxx =$_ ...
- python中self.__class__
1. python中的self python中的self就相当于C++中的this指针也就是指向对象本身的指针self.name = name 就是当前对象的成员变量name赋值为name. 2.py ...
- hdu 4445
今天模拟了一场去年金华的现场赛: 我和小珺两人出了5个题,感觉还可以: 不过这次的题目确实比较简单: 这个题目感觉不错,不难,以前见过用这种方法的,但一直没写过: 这次写下练练手: 思路,将角度分成1 ...
- HDU 4734
数位dp题:也是我做的第一个数位dp的题目: 感觉数位dp的模板性很强啊,思想都差不太多! 有几个写的很好的参考资料: 推荐一下: 数位计数问题解法研究 浅谈数位类统计问题 我的代码: #includ ...
- how to develop mobile web
http://blog.templatemonster.com/2010/05/11/how-make-mobile-website-6-easy-tips/ http://mobile.smashi ...
- Stanford CoreNLP--Part of Speech
Stanford CoreNLP Part Of Speech简称POS,主要是对待分析的句子中的单词进行标记的功能,如标记名词.动词等,该组件是CoreNLP工程的一部分,详细内容可参考:CoreN ...