linux写管道返回 1,linux  1、管道及命名管道

1、管道及命名管道

管道是linux 提供的最早的进程通信

方式之一,是Linux中重要的通信方式,有

无名管道和命名管道(也可以称为有名管

道)两种,是把一个程序的输出直接连接

到另一个程序的输入。常说的管道多指无

名管道,无名管道只能用于具有亲缘关系

的进程之间,并且只能用于单向通信,如

果要实现进程间的双向通信则需要使用两

个无名管道,而命名管道则没有这方面的

限制,如下图。命名管道是一个能在无亲

缘关系的进程之间传送数据的特殊文件,

用fifo来表示。一个或多个进程在一端写

入数据,在另一端由一个进程负责读出。

图 1 无名管道与命名管道对比

a4c26d1e5885305701be709a3d33442f.png

(PS:在我所看过的命名管道实例程序中,当没有指明是非阻塞标志的时候,都是按照阻塞状态处理的。)

2、命名管道的打开及读写规则

2.1 打开规则

命名管道的打开规则比较复杂,重要

原因是open系统调用具有是否阻塞的选项

O_NONBLACK。打开规则如表1所示。

2.2 读写规则

对一个空的,阻塞的命名管道的read

调用将等待,直到有数据可以读时才能继

续执行,与此相反,对一个空的,非阻

塞的fifo的read调用将立刻返回0字节。

对于阻塞的命名管道的write调用将等

待,直到数据可以被写入时才继续执行。

如果请求写入的数据的长度小于等于

PIPE_BUF 的长度,调用失败。

如果请求写入的数据的长度大于

PIPE_BUF字节,将写入部分数据,返回

实际写入的字节数,返回值也可能是0。

3、命名管道通信相关的系统调用

3.1 mkfifo系统调用

#include

#include

int mkfifo(const char * pathname,

mode_t mode);

该系统调用使用指定的文件名创建

fifo。第一个参数是一个路径名,也就是

创建命名管道的位置。第二个参数与open

()函数中的mode 参数相同。如果mkfifo

的第一个参数是一个已经存在的路径名

时,会返回EEXIST错误,所以典型的调

用代码会首先检查,如果返回该错误,那

么直接使用命名管道即可。

3.2 命名管道的读写

#include 

ssize_t read(int fd, void *buf, size_t

count);

ssize_t write(int fd, const void

*buf,

size_t count);

read系统调用将从fd所指向的文件读

出count字节的数据并存入buf指向的数据

区里面,如果执行成功,返回实际读入的

字节数,可能会小于count;执行出错,返

回 - 1。返回 0 表示到达了文件尾。

write系统调用将buf指向的数据区里

面的count字节的数据写入到文件描述符

fd指向的文件里面,返回实际写入的字节

数。如果返回0,表示未写入任何数据。

如果返回 - 1,表示执行出错。

此外,用于一般文件的I/O函数都可

以用于FIFO文件,不再详细介绍,读者可

参考相关文献。

4、实例分析

我们通过两个进程来分析命名管道在

进程通信中的使用,其中一个进程向命名

管道中写入数据,另外一个进程从命名管

道中读取数据。

4.1 读进程(fifor.c)

读进程的代码,篇幅的关系省略了头

文件 :

#def ine f i

fo_name "/home/

fifoserver"

int main(){

int fifo_fd;

int num;

char buf[1024];

if (access(fifo_name,

F_OK)== -1){

fifo_fd = mkfifo(fifo_name, 0777);

}

printf("process %d opening fifo for

read\n", getpid());

f i f o _ f d = o p e n ( f i f

o _ n am e ,

O_RDONLY);

printf("process %d open for read result

%d \n", getpid(), fifo_fd);

num=read(fifo_fd,buf,1024);

printf("process %d read down\n",

getpid());

printf("data read from fifo is:

%s\n",

buf);

(void)close(fifo_fd);

exit(0);

}

gcc fifor.c -o fir

4.2 写进程(fifow.c)

#def ine f i

fo_name "/home/

fifoserver"

int main(){

int fifo_fd;

int num;

char buf[1024];

printf("please input char;\n");

fgets(buf,1024,stdin);

if (access(fifo_name,F_OK)== -1){

fifo_fd=mkfifo(fifo_name, 0777);

}

printf("process %d opening fifo for

write \n", getpid());

f i f o _ f d = o p e n ( f i f o _ n a m e ,

O_WRONLY);

printf("process %d open for write

result %d \n", getpid(), fifo_fd);

num=write(fifo_fd, buf, 1024);

printf("process %d write down\n",

getpid());

printf("data write into fifo is :%s\n",

buf);

(void)close(fifo_fd);

exit(0);

}

gcc fifow.c -o fiw

5、运行结果及分析

a4c26d1e5885305701be709a3d33442f.png

a4c26d1e5885305701be709a3d33442f.png

分析运行结果我们可以看到,当我们输入一段字符到buf之后,首先后

台运行管道写进程fifow, fifow试图为了写

数据而打开管道,此时打印出“process

2884 opening fifo for write”,但是因

为没有进程读打开该管道,所以写进程会

阻塞而不是继续运行,写进程会一直阻塞

到fifor进程读打开命名管道fifoserver。然

后,我们前台运行读进程f i for,读进程

会试图读打开fifo,此时在屏幕上打印出

“process 2900 opening fifo for read”,

在读进程打开命名管道后,写进程继续运

行。 然后, 写进程向管道中写入数据, 写入

的数据会被读进程读出,然后打印在屏幕

转载自http://blog.sina.com.cn/s/blog_664c545f0100t2ke.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值