博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
全双工管道
阅读量:2289 次
发布时间:2019-05-09

本文共 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可以用在非亲缘关系的进程间,而它的真正用途是在服务器和客户端之间. 由于它是半双工的所以,如果要进行客户端和服务器双方的通信的话,

每个方向都必须建立两个管道,一个用于读,一个用于写.

read函数

用于文件描述符对应的文件中读取数据,原型:

ssize_t read(int fd,void*buf,size_t count)

参数说明:
fd: 是文件描述符, 从command line获取数据时,为0
buf: 为读出数据的缓冲区;
count: 为每次读取的字节数(是请求读取的字节数,读上来的数据保
存在缓冲区buf中,同时文件的当前读写位置向后移)

返回值:

成功:返回读出的字节数

失败:返回-1,并设置errno,如果在调用read
之前到达文件末尾,则这次read返回0

write函数

用于将数据写入到文件描述符对应的文件,原型:

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/

你可能感兴趣的文章
SVN检出报错
查看>>
SVN同步版本库
查看>>
网络流量分析工具TCPDUMP
查看>>
系统弱密码检查John
查看>>
用户特权管理
查看>>
Linux软件包管理
查看>>
SUID和SGID可执行文件
查看>>
恢复已删除文件
查看>>
对敏感备份数据加密
查看>>
升级zlib
查看>>
扫描工具nmap
查看>>
linux Rootkit检查
查看>>
日志集中收集工具Syslog-ng+rsyslog+logrotate
查看>>
缓存的作用和重要指标
查看>>
Docker定制私有镜像
查看>>
Docker资源限制
查看>>
Docker容器跨主机通讯
查看>>
Docker单机编排docker-compose
查看>>
Docker数据管理
查看>>
Dockerfile创建镜像
查看>>