您当前的位置: 首页 > 

我什么都布吉岛

暂无认证

  • 3浏览

    0关注

    292博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

进程间通信(四)有名管道

我什么都布吉岛 发布时间:2021-08-10 21:40:32 ,浏览量:3

有名管道解决了无名管道进程只能是具有情缘关系的问题。

一、有名管道

无名管道是临时的,通信完成后自行消失。有名管道或者叫做命名管道(named pipe),可以实现没有亲缘关系的进程间通信,方法是使用FIFO文件。

1.1 shell中使用有名管道

一般而言,Linux中的fifo文件存储在/tmp/my_fifo, shell中可以直接创建fifo:

sudo mkfifo abc

然后进行读取和写入:

cat  /tmp/abc #需要root权限,注意不是sudo权限

cat < filename将文件的内容打印至标准输出,如果此时另一进程将内容写至fifo文件可以直接在终端观察到管道的内容。

1.2 mkfifo创建有名管道

除了在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高级程序设计(第三版)》

关注
打赏
1658157489
查看更多评论
立即登录/注册

微信扫码登录

0.1058s