有名管道解决了无名管道进程只能是具有情缘关系的问题。
一、有名管道无名管道是临时的,通信完成后自行消失。有名管道或者叫做命名管道(named pipe),可以实现没有亲缘关系的进程间通信,方法是使用FIFO文件。
1.1 shell中使用有名管道一般而言,Linux中的fifo文件存储在/tmp/my_fifo
, shell中可以直接创建fifo
:
sudo mkfifo abc
然后进行读取和写入:
cat /tmp/abc #需要root权限,注意不是sudo权限
cat < filename
将文件的内容打印至标准输出,如果此时另一进程将内容写至fifo
文件可以直接在终端观察到管道的内容。
除了在shell中直接创建外,在C/C++程序中使用mkfifo
接口创建:
#include
#include
int mkfifo(const char * filename, mode_t mode);
输入参数:
const char * filename 要打开的fifo
文件
mode_t mode 打开模式
mode含义O_RDONLY只读O_WRONLY只写O_NONBLOCK非阻塞如以只读非阻塞方式打开文件,O_RDONLY|O_NONBLOCK
。
在没有设置O_NONBLOCK
时,读写都可能出现阻塞:
read
当文件为空时阻塞都关闭时,才会立刻返回0。
read是阻塞还是非阻塞读取取决于设备的设置,默认情况都是阻塞读取。
write
当文件为满阻塞
FIFO
文件大小一般为4096byte(4kb)在系统头文件limits.h
PIPE_BUF宏定义。
输出参数 返回一个实际读取的字节数n(n0){ tmp_char_ptr=my_data.some_data; while(*tmp_char_ptr){ *tmp_char_ptr=toupper(*tmp_char_ptr); tmp_char_ptr++; // } sprintf(client_fifo,CLIENT_FIFO_NAME,my_data.client_pid); client_fifo_fd=open(client_fifo,O_WRONLY); if(client_fifo_fd!=-1){ int ttt=write(client_fifo_fd,&my_data,sizeof(my_data)); close(client_fifo_fd); } } }while(read_res>0); close(server_fifo_fd); unlink(SERVER_FIFO_NAME); exit(EXIT_SUCCESS); }
//头文件
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVER_FIFO_NAME "/tmp/server_fifo"
#define CLIENT_FIFO_NAME "/tmp/cli_%d_fifo"
#define BUFFER_SIZE 20
struct data_to_pass_st{
pid_t client_pid;
char some_data[BUFFER_SIZE-1];
};
三、小结
管道是一种抽象的概念,它充当了进程间信息交互的桥梁。常见的两种管道如下:
- 有名管道
- 无名管道
其中有名管道拥有更加丰富的访问控制规则,适用于没有亲缘关系的管道。无名管道则需要进程间有亲缘关系。
【1】《Linux程序设计(第五版)》 【2】《Linux高级程序设计(第三版)》