linux有名管道读写函数,Linux C 编程----有名管道FIFO

有名管道FIFO简介:

有名管道的创建可以使用函数mkfifo(),该函数类似于文件中的open()操作,可以指定管道的路径和打开的模式。用户还可以在命令行使用“mknod 管道名 p”来创建有名管道。

在创建管道成功后,就可以使用open()、read()和write()这些函数了。与普通文件的开发设置一样,对于为读而打开的管道可 在open()中设置O_RDONLY,对于为写而打开的管道可在open()中设置O_WRONLY,在这里与普通文件不同的是阻塞问题。由于普通文件 在读写时不会出现阻塞问题,而在管道的读写中却有阻塞的可能,这里的非阻塞标志可以在open()函数中设定为O_NONBLOCK。下面分别对阻塞打开 和非阻塞打开的读写进行讨论。

对于读进程:

● 若该管道是阻塞打开,且当前FIFO内没有数据,则对读进程而言将一直阻塞到有数据写入。

● 若该管道是非阻塞打开,则不论FIFO内是否有数据,读进程都会立即执行读操作。即如果FIFO内没有数据,则读函数将立刻返回0。

对于写进程:

● 若该管道是阻塞打开,则写操作将一直阻塞到数据可以被写入。

● 若该管道是非阻塞打开而不能写入全部数据,则读操作进行部分写入或者调用失败。

有名管道FIFO特点:

(1)它可以使互不相关的两个进程实现彼此通信。

(2)该管道可以通过路径名来指出,并且在文件系统中是可见的。在建立来管道之后,两个进程就可以把它当作普通文件一样进行读/写操作,使用非常方便。

(3)FIFO 严格地遵循先进先出规则,对管道及 FIFO 的读总是从开始处返回数据,对它们的写则把数据添加到末尾,它们不支持如 lseek() 等文件定位操作。

表1列出了mkfifo()函数的语法要点。

注意:mkfifo() 函数仅仅是创建了管道,但并没有打开管道!

表1 mkfifo()函数语法要点

所需头文件

#include    #include

函数原型

int mkfifo(const char *filename,mode_t mode)

函数传入值

filename:要创建的管道

mode

O_RDONLY:读管道

O_WRONLY:写管道

O_RDWR:读写管道

O_NONBLOCK:非阻塞

O_CREAT:如果该文件不存在,那么就创建一个新的文件,并用第3个参数为其设置权限

O_EXCL:如果使用O_CREAT时文件存在,那么可返回错误消息。这个参数可测试文件是否存在

函数返回值

成功:0

出错:-1

表2再对FIFO相关的出错信息进行归纳,以方便用户查错。

表2  FIFO相关的出错信息

EACCESS

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

EEXIST

参数filename所指定的文件已存在

ENAMETOOLONG

参数filename的路径名称太长

ENOENT

参数filename包含的目录不存在

ENOSPC

文件系统的剩余空间不足

ENOTDIR

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

EROFS

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

函数调用实例:

/* 创建有名管道,并设置相应的权限 */

mkfifo("myfifo",0666) //可读可写

/* 以读写方式打开有名管道,并设置非阻塞标志 */

fd = open("myfifo",O_RDWR|O_NONBLOCK);

以下是一个简单的FIFO管道程序,此程序有很多缺陷,最大的缺陷是,fifo_write.c 只能发送一个词(也就是发送的字符串中不能有空格!)

fifo_write.c

#include  //write,read,close,access

#include   //printf,sscanf,

#include  //memset,

#include  // PIPE_BUF

#include   //open,O_RDONLY....;

#include  //exit,

#define MYFIFO "/tmp/myfifo"

#define MAX_BUFFER_SIZE PIPE_BUF

int main(int argc, char *argv[])

{

int fd;

int nwrite;

char buff[MAX_BUFFER_SIZE];

if(argc <= 1)

{

printf("Usage: ./fifo_write string\n");

exit(1);

}

sscanf(argv[1],"%s",buff);

fd = open(MYFIFO,O_WRONLY);

if(fd == -1)

{

printf("Open fifo file error\n");

exit(1);

}

nwrite = write(fd,buff,MAX_BUFFER_SIZE);

if(nwrite > 0)

{

printf("Write '%s' to FIFO\n", buff);

}

close(fd);

exit(0);

}

fifo_read.c

#include  //mkfifo

#include   //mkfifo

#include     //PIPE_BUF

#include     //read,write,close,access

#include     //memset

#include      //printf

#include     //exit

#include      //open,open---O_RDONLY...,

#include      //errno

#define MYFIFO "/tmp/myfifo"

#define MAX_BUFFER_SIZE PIPE_BUF

int main()

{

int fd,mm,nread;

char buff[MAX_BUFFER_SIZE+1];

if(access(MYFIFO,F_OK) == -1)

{

mm = mkfifo(MYFIFO,0666);

if((mm 

{

printf("mkfifo error!");

exit(1);

}

}

memset(buff,'\0',sizeof(buff));

while(1)

{

fd = open(MYFIFO,O_RDONLY);

if(fd == -1)

{

printf("open error!");

exit(1);

}

nread = read(fd,buff,MAX_BUFFER_SIZE);

if(nread > 0)

{

printf("Read '%s' from FIFO\n",buff);

}

close(fd);

}

exit(0);

}

PIPE_BUF /* 定义在limits.h中 */

sscanf与scanf类似,都是用于输入的,只是后者以键盘(stdin)为输入源,前者以固定字符串为输入源。

fifo 有名管道详细分析见Linux命名管道FIFO的读写规则 以及该博主的其他相关博客。

更多内容,详见于http://www.farsight.com.cn/news/emb201.htm

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值