FIFO是有名管道,与管道一样,也是半双工的通信方式,但FIFO是命名管道,所以非父子关系的进程可以通过管道名Open管道,进行读写处理。
特点
- 半双工模式,同一时间一端只能接收或发送数据。
- FIFO是创建在真实文件系统中的,
ls
是可以看到的。 - 创建的FIFO只有在调用
unlink(fifoName)
才会被删除。 - 如果FIFO中没有数据,则读取管道数据的进程会发生读阻塞。
- 如果FIFO被写满了,则会发生写阻塞。
使用场景
多进程间的通信,因为是半双工模式,所以如果想在2个进程间互通消息,则需要创建2个FIFO。又因为是有名管道,所以通信两端需要提前知道彼此FIFO的名字。
创建FIFO
unlink()
删除
mkfifo()
新建
open()
打开
close()
关闭
示例代码
下面的例子是2个独立进程,app1读数据,app2写数据。
省略了部分容错处理。
【app1】
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;
#define FIFO_PATH "/tmp/fifo1"
int main()
{
char buf[100] = {"\n"};
int fd = open(FIFO_PATH, O_RDONLY);
while (1) {
ssize_t len = read(fd, buf, sizeof(buf));
if (!len)
break;
cout << string(buf) << endl;
}
return 0;
}
【app2】
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;
#define FIFO_PATH "/tmp/fifo1"
int main()
{
string str = "Hello";
unlink(FIFO_PATH);
int ret = mkfifo(FIFO_PATH, 0777);
if (ret != 0) {
cout << "mkfifo error" << endl;
return -1;
}
int fd = open(FIFO_PATH, O_WRONLY);
for (int iCount = 0; iCount < 10; iCount++) {
string strTmp = str + to_string(iCount);
write(fd, strTmp.c_str(), strTmp.length());
sleep(2);
}
close(fd);
unlink(FIFO_PATH);
return 0;
}