Linux的进程编程-之二-进程间通信(管道)
来源:互联网 发布:看肚脐知健康 编辑:程序博客网 时间:2024/05/19 03:46
1.1 管道
管道可用于具有亲缘关系(父子进程或者兄弟进程)之间的通信,管道具有以下特点:
1.管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;
2.管道对于两端的进程而言,就是一个文件,但它不属于文件系统,只存在于内存中;
3.每次写入的内容都添加在管道缓冲区的末尾,每次都是从管道缓冲区的头部读出数据;
4.管道没有名字;
5.管道缓冲区是有限的(PIPE_BUF);
6.文件的I/O函数都可以用于管道,如open( )、close( )、read( )、write( ) 、fcntl( )。
1.1.1 管道的创建
#include<unistd.h>
intpipe( int fd[2] )
fd[0]是管道读端;fd[1]是管道写端。父进程用pipe( )创建管道后,一般再fork()出一个子进程,然后通过管道实现父子进程间的通信。
成功返回0,失败返回-1。
1.1.2 有名管道的创建
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo( const char * name, mode_t mode )
参数name指定与FIFO相关联的名字;成功返回0,失败返回-1。
有名管道(named pipe或FIFO)以FIFO文件的形式存在于文件系统中,因此即使没有亲缘关系的进程也能通过FIFO进行通信。
1.1.3 管道的打开
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
intopen( const char *name, int flags )
int open( const char *name, int flags, mode_t mode )
参数name指定了文件名(包含路径),当前进程必须能够访问该文件。
成功返回文件描述符fd,失败返回-1。
参数flags可以取:
O_RDONLY O_WRONLY O_RDWR(三选一)
O_CREAT
单独使用O_CREAT,如果name指定的文件不存在,就创建该文件,并返回其描述符;如果name指定的文件已经存在,就返回该文件的描述符。如果指定了O_CREAT,需要使用open( )的第二种形式,其中参数mode指定了新创建文件的访问权限。
用户
组成员
其他成员
S_IXUSR
100
S_IXGRP
010
S_IXOTH
001
S_IWUSR
200
S_IWGRP
020
S_IWOTH
002
S_IRUSR
400
S_IRGRP
040
S_IROTH
004
S_IRWXU
700
S_IRWXG
070
S_IRWXO
007
O_EXCL
单独使用O_EXCL是没有意义的,如果O_EXCL和O_CREAT一起使用,当name指定的文件已经存在时,就失败返回。
O_APPEND :确保每次对文件进行写操作之前,文件偏移指针都会被重新定位到文件末尾
O_NOCTTY :如果打开的文件是终端设备,确保该终端设备不会成为当前进程的控制终端
O_TRUNC :清空文件内容,如果同时满足以下条件:文件已经存在&&文件是普通文件&&文件能够成功open&&open时指定支持写操作(O_WRONLYor O_RDWR)
O_NONBLOCK:
1.如果open的是FIFO,而且open时指定支持单一读写操作(O_RDONLYor O_WRONLY):
1.1.指定O_NONBLOCK:
单一读打开的open,立即返回;
单一写打开的open,如果还没有其它进程读打开该FIFO,返回-1。
1.2.未指定O_NONBLOCK:
单一读打开的open会挂起当前进程,直到有其它进程写打开FIFO;
单一写打开的open会挂起当前进程,直到有其它进程读打开FIFO。
2.如果open的文件或设备支持非阻塞打开:
2.1.指定O_NONBLOCK:open会立即返回,不用等待打开的文件或设备ready or available
2.2.未指定O_NONBLOCK:open会挂起当前进程,直到打开的文件或设备ready or available
1.1.4 管道的关闭
#include<unistd.h>
intclose( int fd )
成功返回0,失败返回-1。
1.1.5 从管道中读取数据
1.1.5.1 read( )
#include<unistd.h>
ssize_tread( int fd, void * buf, size_t nbyte )
从fd指定的文件中读取nbyte字节到buf中,返回实际读取到的字节数(可能小于nbyte)。
返回0表明文件为空(读到EOF),读取失败返回-1。
当试图从一个空的FIFO中读取数据时:
1.如果没有其它进程写打开FIFO,read( )返回0;
2.如果有其它进程写打开FIFO:
2.1.当前进程读打开时指定了O_NONBLOCK,read( )返回-1;
2.2.当前进程读打开时未指定O_NONBLOCK,read( )挂起当前进程,直到有数据写入该FIFO,或者是所有写打开该FIFO的进程都关闭了它。
当试图从一个支持非阻塞读操作,但却没有数据available的文件或设备中读取数据时:
1.如果在读打开时指定了O_NONBLOCK,read( )返回-1;
2.如果在读打开时未指定O_NONBLOCK,read( )将挂起当前进程,直到有数据写入。
1.1.5.2 readv
#include<sys/uio.h>
ssize_treadv( int fd, const struct iovec *iov, int iovcnt )
readv( )将读取出来的数据依次存放到一系列内存单元中(iov[0], iov[1], ..., iov[iovcnt-1])。
struct iovec
{
void * iov_base; // baseaddress of the memory
size_t iov_len; // size ofthe memory
}
1.1.6 向管道中写入数据
1.1.6.1 write( )
#include<unistd.h>
ssize_twrite( int fd, const void * buf, size_t nbyte )
向fd指定的文件中写入nbyte字节的数据,数据来源为buf,返回实际写入的字节数(可能小于nbyte)。写入失败返回-1。
当向FIFO写入时:
1.如果写打开时未指定O_NONBLOCK,write挂起当前进程,直到全部nbyte写入完毕;
2.如果写打开时指定了O_NONBLOCK,write执行以下写入操作后,立即返回:
2.1.nbyte≤PIPE_BUF,但FIFO中的剩余空间不足,write不写入任何数据,立即返回-1;
2.2.nbyte>PIPE_BUF,write会尽可能多的向FIFO中写入数据,立即返回写入的字节数;如果之前存在于FIFO中的数据被读取了,write最终能够向FIFO中写入PIPE_BUF个字节;
2.3.nbyte>PIPE_BUF,但FIFO中确实一个字节也写不进去了,立即返回-1。
所以总的来看,只要nbyte≤PIPE_BUF,不管有没有指定O_NONBLOCK,都可以保证FIFO写入操作的原子性。
当试图向一个支持非阻塞写操作的文件或设备中写入数据时,如果该文件或设备不能马上接收写入的数据,则:
2.如果在写打开时未指定O_NONBLOCK,write( )将挂起当前进程,直到数据能够写入。
1.如果在写打开时指定了O_NONBLOCK,write( )会尽可能多的向文件或设备中写入数据,并返回成功写入的字节数;如果确实一个字节也写不进去,write( )就返回-1。
1.1.6.2 writev( )
#include<sys/uio.h>
ssize_twritev( int fd, const struct iovec *iov, int iovcnt )
writev( )将需要写入的数据依次存放到一系列内存单元中(iov[0], iov[1], ..., iov[iovcnt-1])。
如果所有内存单元的长度之和大于SSIZE_MAX,writev失败返回-1,不进行任何数据写入。
- Linux的进程编程-之二-进程间通信(管道)
- Linux的进程编程-之二-进程间通信(管道)
- Linux环境编程之IPC进程间通信(二):管道
- 进程通信之(二)进程的管道通信实验
- Linux进程间通信(二)管道
- linux基础编程:进程通信之管道
- linux基础编程:进程通信之管道
- 命名管道(FIFO) Linux进程进程间的通信之命名管道(FIFO)
- Linux编程基础之进程间通信之二:有名管道
- Linux进程间通信之管道通信
- Linux进程间通信之管道通信
- Linux进程间通信二之管道(含代码)
- linux系统编程之管道实现父系进程间通信
- Linux编程基础之进程间通信之一:无名管道
- Linux编程学习之进程间通信篇-有名管道
- Linux编程学习之进程间通信篇-无名管道
- linux进程间的通信之管道通信
- Linux编程:进程间通信--管道
- Linux下运用MMAP在进程间通信
- Linux的进程编程-之一-基本概念
- C++ 容易忽略的特性
- Linux的进程编程-之二-进程间通信(信号)
- ExtJS Component分析
- Linux的进程编程-之二-进程间通信(管道)
- 从bootm 命令讲起/U-boot的环境变量: bootcmd 和bootargs
- 腾讯 vs 百度
- vs2008+Qt+MySql环境搭建及提示"Driver not load"的原因分析
- Linux的进程编程-之二-进程间通信(定时器)
- 2011百校联动“菜鸟杯”程序设计公开赛&&Cover The Enemy
- Linux的进程编程-之二-进程间通信(信号灯-Semaphore)
- ognl初接触
- linux idr机制