linux mkfifo 命令_Linux—mkfifo函数使用

Linux pipe 管道到底是什么? 跟踪mkfifo到内核

Thursday, 15. March 2007, 03:31:32

[By

Xalanz]技术问题往往都是这样,当它不出问题的时候,你并不会有特别的兴趣去究根问底,所以,出了问题,往往就是好事.Linux

的Pipe 出了一个问题,我不得不问自己,Pipe 到底是什么,在Linux kernel 里面是怎么实现的.

(1)第一步,你调用了mkfifo()或者使用mkfifo命令,在磁盘文件系统中建立了一个有名字的fifo

文件,但是mkfifo并不是一个系统调用,mkfifo()最终调用了mknod()系统调用来执行实际的功能。

(2)mknod()系统调用的内核部分是在linux\fs\namei.c

文件中sys_mknod()实现对系统调用的接口。

(2)对于fifo,sys_mknod()进一步调用虚拟文件系统的统一接口vfs_mknod()。

(3)而vfs_mknod()将调用相应目录的inode节点的mknod()方法来执行真正的mknod()操作。

1、Pipe 在那个子系统实现的? 在网络子系统、还是进程间通讯部分,还是什么?

Pipe 是在文件系统部分实现的。

2、Pipe 文件还是什么?

Pipe 是一种特殊的文件系统。

********************************************************************************************

mkfifo(建立实名管道)

相关函数

pipe,popen,open,umask

表头文件

#include

#include

定义函数

int

mkfifo(const char * pathname,mode_t mode);

函数说明

mkfifo()会依参数pathname建立特殊的FIFO文件,该文件必须不存在,而参数mode为该文件的权限(mode%~umask),因此

umask值也会影响到FIFO文件的权限。Mkfifo()建立的FIFO文件其他进程都可以用读写一般文件的方式存取。当使用open()来打开

FIFO文件时,O_NONBLOCK旗标会有影响

1、当使用O_NONBLOCK 旗标时,打开FIFO 文件来读取的操作会立刻返回,但是若还没有其他进程打开FIFO

文件来读取,则写入的操作会返回ENXIO 错误代码。

2、没有使用O_NONBLOCK 旗标时,打开FIFO

来读取的操作会等到其他进程打开FIFO文件来写入才正常返回。同样地,打开FIFO文件来写入的操作会等到其他进程打开FIFO

文件来读取后才正常返回。

返回值

若成功则返回0,否则返回-1,错误原因存于errno中。

错误代码

EACCESS

参数pathname所指定的目录路径无可执行的权限

EEXIST

参数pathname所指定的文件已存在。

ENAMETOOLONG

参数pathname的路径名称太长。

ENOENT

参数pathname包含的目录不存在

ENOSPC

文件系统的剩余空间不足

ENOTDIR

参数pathname路径中的目录存在但却非真正的目录。

EROFS

参数pathname指定的文件存在于只读文件系统内。

示例1:

#include

#include

#include

#include

int main(void)

{

char

buf[80];

int

fd;

unlink(

"zieckey_fifo" );

mkfifo(

"zieckey_fifo", 0777 );

if ( fork()

> 0 )

{

char s[] =

"Hello!\n";

fd = open(

"zieckey_fifo", O_WRONLY );

write( fd,

s, sizeof(s) );

//close( fd

);

}

else

{

fd = open(

"zieckey_fifo", O_RDONLY );

read( fd,

buf, sizeof(buf) );

printf("The

message from the pipe is:%s\n", buf );

//close( fd

);

}

return

0;

}

执行

hello!

示例2: #include

#include

#include

#include

#include

int main( int argc, char **argv )

{

mode_t mode

= 0666;

if ( argc

!=2 )

{

printf(

"Usage:[%s] fifo_filename\n", argv[0] );

return

-1;

}

if (mkfifo(

argv[1], mode)<0 )

{

perror(

"mkfifo");

return

-1;

}

return

0;

}

***************************************************************************************

最近做的项目遇到一个问题:把播放器模块和UI模块整合成一个可执行程序,整合好后,一运行报出一个运行时错误,什么free一个地址出错了。这种问题是内存操作引起的,很难找出原因,而且这问题也不知道是UI模块还是播放器模块引起的,真是摸不着头脑。

后来想想,把播放器编译成一个单独的可执行程序,UI也是单独的可执行程序,然后两者之间通过管道来实现进程间的通信。我使用的是命名管道,其实命名管道的创建和使用也不算太难:

1、mkfifo创建一个管道,需要加一些创建标志,如O_CREAT等;

2、使用open函数来获取管道描述符,这个关键点也是设置标志,如O_NONBLOCK,O_RDONLY,

O_WRONLY等。

3、然后在一个进程中使用write进行写,在另外一个进程中使用read进行读。这样就构造了一个单双工的通道。可以再创建一个管道来进行反向通信,从而实现双向通信。

4、退出时使用unlink把管道文件删除掉。

大概的步骤就是这样,关键是根据需要创建合适的通讯模式。

注意:

我在open的时候使用了O_NONBLOCK |

WRONLY标志,然后出错了,返回-1。后来查看errno才知道,使用了O_NONBLOCK标志,必须先有进程以读的方式打开这个管道,才能以O_NONBLOCK

| WRONLY标志来打开这个管道。

***************************************************************************************

讲述了管道和有名管道的用法

原文链接:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值