与无名管道不同,有名管道FIFO可以在两个无关进程间使用。
#include <sys/stat.h> int mkfifo(const char* path, mode_t mode);
上述函数用于生成一个FIFO文件,其中的mode参数与open函数中的mode相同。当创建了FIFO文件后,要用open函数来打开它。
当open一个FIFO时,非阻塞标志(O_NONBLOCK)会有如下影响:
|
O_NONBLOCK标志 |
详 细 说 明 |
|
置位 |
只读open立即返回;只写open时,如果没有进程为读打开FIFO,则返回–1,并置errno值为ENXIO |
|
不置位 |
open视情况阻塞。只读open要阻塞到有进程为写打开FIFO;只写open要阻塞到有进程为读打开FIFO |
两点注意:
1、如果write一个尚无进程为读而打开的FIFO,则产生信号SIGPIPE。
2、如果某个FIFO的最后一个写进程关闭了该FIFO,则将为该FIFO的读进程产生一个文件结束标志。
举例:两个程序,一个读,一个写,且写程序加了SIGPIPE信号处理函数,读程序在读到结束符后加了打印,可以验证上面所有描述。
fifo_read.cpp:
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string>
#include <iostream>
int main()
{
const char* path = "/tmp/tmp_fifo";
// 判断是否有fifo文件,没有就创建一个
if(access(path, F_OK) == -1)
{
printf("create %s\n",path);
if(mkfifo(path,0777) == -1)
{
printf("create failed\n");
return -1;
}
}
int pipe_fd = open(path, O_RDONLY);//只读模式打开
if(pipe_fd < 0)
{
printf("open %s failed\n",path);
return -1;
}
else
{
printf("open %s success\n",path);
}
char buf[128] = {0};
while(read(pipe_fd, buf, 128))
{
printf("read: %s\n",buf);
}
printf("read end\n");
close(pipe_fd);
return 0;
}
fifo_write.cpp:
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include <signal.h>
void handler(int arg)
{
printf("signal PIPE\n");
}
int main()
{
signal(SIGPIPE, &handler);
const char* path = "/tmp/tmp_fifo";
// 判断是否有fifo文件,没有就创建一个
if(access(path, F_OK) == -1)
{
printf("create %s\n",path);
if(mkfifo(path,0777) == -1)
{
printf("create failed\n");
return -1;
}
}
int pipe_fd = open(path, O_WRONLY);//只写模式打开
if(pipe_fd < 0)
{
printf("open %s failed\n",path);
return -1;
}
else
{
printf("open %s success\n",path);
}
char buf[128] = {0};
std::string str;
while(std::cin>>str)
{
write(pipe_fd, str.c_str(), str.size());
printf("write : %s\n",str.c_str());
}
close(pipe_fd);
return 0;
}
原文:https://www.cnblogs.com/ho966/p/12254103.html