开启辅助访问 切换到窄版

打印 上一主题 下一主题

Linux进程间通信之管道、消息队列实践

[复制链接]
作者:ln留恋 
版块:
嵌入式操作系统 linux 发布时间:2021-4-11 09:02:51
15110
楼主
跳转到指定楼层
| 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1、进程间通信简述进程间通信的几种方式:无名管道、有名管道、消息队列、共享内存、信号、信号量、套接字(socket)。
进程间通信是不同进程直接进行的一些接触,这种接触有简单,有复杂。机制不同,复杂度也不同。通信是一个广义上的意 义,不仅指大批量数据传送,还包括控制信息的传送,但是使用的方法都是大同小异的。
如图所示进程不是孤立的,不同的进程需要进行信息的交互和状态的传递等,因此需要进程间通信。2、管道管道分为无名管道和有名管道两种方式。管道是一种半双工的通信方式,数据只能单向流动,但是无名管道和有名管道的区别是无名管道只能在具有亲缘关系的进程间通信,有名管道则是在无亲缘关系进程间通信。进程的亲缘关系通常是指父子进程关系。管道是Linux支持的最初Unix IPC形式之一,管道与管道之间通信其实就是一个文件,但它不是一个普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统而且只存在内存中。当一个进程向管道中写的内容被管道另一端的进程读出;写入的内容每次都会被添加到管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。如下图所示。
那么,如何创建一条管道呢?下面,我们就来了解下FIFO函数。FIFO不同于pipe函数,因为它提供了一个路径名与之关联,以FIFO的文件形式存在于文件系统中,这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径就能够彼此通过FIFO互相通信,因此,通过FIFO不相关的进程也能交换数据。值得注意的是,FIFO严格遵循先进后出,和栈的原则一样,对管道以及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾。它们不支持诸如lseek等文件定位操作。需要包含的头文件如下:int mkfifo(const char *pathname,mode_t mode);
函数返回值 :成功0,失败-1参数含义:pathname为路径名,创建管道的名字(该函数的第一个参数是一个普通的路径名,也就是创建后FIFO的名字)。mode为创建fifo的权限(第二个参数与打开普通文件的open函数中的mode参数相同)。注:如果mkfido的第一个参数已经是一个已经存在的路径名时,就会返回EEXIST错误,所以当我们调用的时候首先会检查是否返回该错误,如果返回该错误那我们只需要直接调用打开FIFO的函数即可。FIFO比pipe函数打开的时候多了一个打开操作open;如果当时打开操作时为读而打开FIFO时,若已经有相应进程为写而打开该FIFO,则当前打开操作将返回成功;否则,可能阻塞到有相应进程为写而打开该FIFO;或者,成功返回。另一种情况就是为写而打开FIFO时,若已经有相应进程为读而打开该FIFO,则当前打开操作将成功返回;否则可能会阻塞直到有相应进程为读而打开该FIFO;或者,返回ENIO错误。下面我们使用FIFO实现进程间的通信。(1)打开一个文件,管道的写入端向文件写入数据;管道的读取端从文件中读取出数据。fifo_write.c
#include
#include
#include
#include
#include
#include

#define P_FIFO "txt"

int main
{
int ret;
int fd;
char buf[20];
//打开有名管道
//第一个参数为有名管道文件路径
//第二个参数表明是以读取方式并以非阻塞方式打开有名管道
//O_RDONLY读取模式
//O_NONBLOCK非阻塞方式
fd = open(P_FIFO,O_RDONLY);
if(fd

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表