本文共 1973 字,大约阅读时间需要 6 分钟。
Fork() 函数:
返回0时是子进程,否则,是父进程。
pipe函数
int pipe(int filedes[2]);
返回值:成功,返回0,否则返回-1。参数数组包含pipe使用的两个文件的描述符。fd[0]:读管道,fd[1]:写管道。
必须在fork()中调用pipe(),否则子进程不会继承文件描述符。两个进程不共享祖先进程,就不能使用pipe。但是可以使用命名管道。
当管道进行写入操作的时候,如果写入的数据小于128K则是非原子的,如果大于128K字节,缓冲区的数据将被连续地写入
管道,直到全部数据写完为止,如果没有进程读取数据,则将一直阻塞
命名管道FIFO
管道最大的劣势就是没有名字,只能用于有一个共同祖先进程的各个进程之间。FIFO代表先进先出,单它是一个单向数据流,也就是半双工,和
管道不同的是:每个FIFO都有一个路径与之关联,从而允许无亲缘关系的进程访问。
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char *pathname, mode_t mode);
这里pathname是路径名,mode是sys/stat.h里面定义的创建文件的权限.以下示例程序来自:http://blog.chinaunix.net/uid-20498361-id-1940238.html
从例子上可以看出使用fifo时需要注意:
*fifo管道是先调用mkfifo创建,然后再用open打开得到fd来使用. *在打开fifo时要注意,它是半双工的的,一般不能使用O_RDWR打开,而只能用只读或只写打开. fifo可以用在非亲缘关系的进程间,而它的真正用途是在服务器和客户端之间. 由于它是半双工的所以,如果要进行客户端和服务器双方的通信的话,每个方向都必须建立两个管道,一个用于读,一个用于写.
用于文件描述符对应的文件中读取数据,原型:
ssize_t read(int fd,void*buf,size_t count)
参数说明: fd: 是文件描述符, 从command line获取数据时,为0 buf: 为读出数据的缓冲区; count: 为每次读取的字节数(是请求读取的字节数,读上来的数据保 存在缓冲区buf中,同时文件的当前读写位置向后移)
返回值:
成功:返回读出的字节数
失败:返回-1,并设置errno,如果在调用read 之前到达文件末尾,则这次read返回0
用于将数据写入到文件描述符对应的文件,原型:
ssize_t write(int fd,const void*buf,size_t count);
参数说明: fd:是文件描述符(输出到command line,就是1) buf:通常是一个字符串,需要写入的字符串 count:是每次写入的字节数
返回值:
成功:返回写入的字节数
失败:返回-1并设置errno ps: 写常规文件时,write的返回值通常等于请求写的字节 数count, 而向终端设备或者网络写时则不一定
实例:
以下程序再提供全双工管道的系统下,能够看到
child read p
parent read c
再默认提供半双工管道的系统下,则会出错。
#include "unpipc.h"int main(int argc,char **argv){ int fd[2],n; char c; pid_t childpid; Pipe(fd); if((childpid = Fork()) == 0){ sleep(3); printf("sleep over !\n"); if((n = Read(fd[0],&c,1))!=1){ printf("read err \n"); err_quit("child: read returned %d",n); } printf("child test \n"); printf("child read %c\n",c); Write(fd[0],"d",1); //exit(0); } printf("parent do \n"); Write(fd[1],"p",1); printf("parent write over ! \n"); sleep(4); if((n = Read(fd[1],&c,1))!=1){ printf("parent read error ! \n"); err_quit("parent: read returned %d",n); } printf("parent read %c\n",c); exit(0);}
参考:
转载地址:http://qfbnb.baihongyu.com/