有名管道FIFO

一、函数原型
         #include <sys/stat.h>
#include <sys/types.h>
int mkfifo( const char * filename, mode_t mode );
  功能:创建有名管道 FIFO  
  参数:
                    filename:指定新创建FIFO的文件名称(包含路径名)
          mode:指定FIFO的读写权限,和 open 函数的mode参数一样。新创建FIFO的用户ID和组ID规则域open 函数相同 
        返回值:函数如果成功返回0,出 错返回–1,并更改errno的值



二、有名管道特性
  
    当调用open()来打开 FIFO文件时,O_NONBLOCK会有影响
  • 没有指定O_NONBLOCK时,有名管道需要用open函数打开以后使用,如果以只读方式打开,会阻塞到有写方式打开管道,同样以只写方式打开会阻塞到以读方式打开。
  • 如果指定了O_NONBLOCK,则只读open会立即返回。但是,如果没有进程已经为读而打开一个 FIFO ,那么只写open将会收到一个SIGPIPE信号,终止进程
  • 有名管道FIFO可以用在没有亲缘关系的进程中


三、注意事项

  • fifo文件并不存在磁盘上,磁盘上只存其属性和链接等。
  • 读FIFO时,如果没有写入数据,read要阻塞到有某个其他进程将数据写入。
  • 写 FIFO时,如果如果FIFO有足够空间,write函数会返回写入的字节数;如果空间不够,write函数会阻塞,直到有空间供其写入为止
    PS:此阻塞是由 read和  write 函数引起的阻塞,和先前  open  打开 FIFO 时的阻塞不一样
  • 在对管道读的过程中,如果写端关闭,则读一个写端已关闭的  FIFO 时,read 返回。如果将读端关闭, 则写一个读端关闭的管道,则产生SIGPIPE信号,程序退出。如果忽略该信号或者捕捉该信号并处理程序返回,则write返回-1,errno设置为EPIPE 
  • write和read会同样使管道文件偏移量改变。但无法使用lseek对FIFO操作 
  • 当写入管道的数据小于PIPE_BUF时,write操作是一个原子操作。
  • 说明:在服务器端打开公共FIFO的时候,如果仅以只读打开,则当所有的客户端都退出时,服务器端会读取到文件结束符。这个问题的解决办法是服务器以读写打开公共FIFO

例程:
fifor.c文件:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <error.h>
#include <errno.h>

#define error_exit(_errmsg_) error(EXIT_FAILURE, errno, _errmsg_)

#define FIFO_PATH "/tmp/fifo926"
#define BUFF_SIZE 1024

int main()
{
int fd;
char *buff = NULL;

if (-1 == mkfifo(FIFO_PATH, 0666)) {
if (EEXIST != errno)
error_exit("mkfifo");
}

puts("before open ... ");
if (-1 == (fd = open(FIFO_PATH, O_RDONLY)))
error_exit("open");
puts("after open ... ");

buff = (char *)malloc(BUFF_SIZE);

if (-1 == read(fd, buff, BUFF_SIZE))
error_exit("write");

puts(buff);

close(fd);
free(buff);

return 0;
}

fifow.c文件:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <error.h>
#include <errno.h>

#define error_exit(_errmsg_) error(EXIT_FAILURE, errno, _errmsg_)

#define FIFO_PATH "/tmp/fifo926"
#define BUFF_SIZE 1024

int main()
{
int fd;

if (-1 == mkfifo(FIFO_PATH, 0666)) {
if (EEXIST != errno)
error_exit("mkfifo");
}

puts("before open ... ");
if (-1 == (fd = open(FIFO_PATH, O_WRONLY)))
error_exit("open");
puts("after open ... ");

if (-1 == write(fd, "helloworld", 11))
error_exit("write");

close(fd);

return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值