IPC通信_有名管道(FIFO)

Posted ho966

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IPC通信_有名管道(FIFO)相关的知识,希望对你有一定的参考价值。

  与无名管道不同,有名管道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;
}

  

 

以上是关于IPC通信_有名管道(FIFO)的主要内容,如果未能解决你的问题,请参考以下文章

IPC之套接字

3.2 进程间通信之fifo

14.有名管道通信

ipc_pipe

有名管道fifo

进程间通信->有名管道