Linux进程间通信 |
您所在的位置:网站首页 › 修改英文文章的软件 › Linux进程间通信 |
1. 进程间通信概述
进程间通信(Inter-Process Communication, IPC)是指在两个或者多个不同得劲进程间传递或者交换信息,通过信息的传递建立几个进程间的联系,协调一个系统中的多个进程之间的行为。 1.1 进程间通信的工作原理 进程与进程之间是相互独立的,各自运行在自己的虚拟内存中。要想在进程与进程间建立联系,需要通过内核,在内核中开辟一块缓冲区,两个进程的信息在缓冲区中进行交换或者传递。其原理如下图所示。 管道与命名管道是最基本的IPC机制之一。管道主要用于父子或者兄弟进程间的数据读写,命名管道则可以在无关联的进程间进行沟通传递数据。 2.1 管道的基本定义 所谓管道,就像生活中的煤气管道、下水管道等传输气体和液体的工具,而在进程通信意义上的管道就是传输信息或数据的工具。以下水管道为例,当从管道一端输送水流到另一端时,只有一个传输方向,不可能同时出现两个传输方向。在Linux系统中的进程通信中,管道这个概念也是如此,某一时刻只能单一方向传递数据,不能双向传递数据,这种工作模式就叫做半双工模式。半双工工作模式的管道通信是只能从一端写数据,从另一端读数据。 2.2 管道创建和管道关闭 管道由Linux系统提供的pipe()函数创建,该函数原型为: #include int pipe(int filedes[2]);pipe()函数用于在内核中创建一个管道,该管道一端用于读取管道中的数据,另一端用于将数据写入管道。在创建一个管道后,会获得一对文件描述符,用于读取和写入,然后将参数数组filedes中的两个值传递给获取到的两个文件描述符,filedes[0]指向管道的读端,filedes[1]指向写端。 pipe()函数调用成功,返回值为0;否则返回-1,并且设置了适当的错误返回信息。此函数只是创建了管道,要想从管道中读取数据或者向管道中写入数据,需要使用read()和write()函数来完成。当管道通信结束后,需要使用close()函数关闭管道的读写端。 2.3 pipe()函数实现管道通信 (1)在父进程中调用pipe()函数创建一个管道,产生一个文件描述符filedes[0]指向管道的读端和另一个文件描述符filedes[1]指向管道的写端。 (2)在父进程中调用fork()函数创建一个一模一样的新进程,也就是所谓的子进程。父进程的文件描述符一个指向读端,一个指向写端。子进程同理。 (3)在父进程关闭指向管道写端的文件描述符filedes[1],在子进程中,关闭指向管道读端的文件描述符filedes[0]。此时,就可以将子进程中的某个数据写入到管道,然后在父进程中,将此数据读出来。 过程如下图所示: 结果: ![]() 以上介绍的管道通信的方法有很多限制。受限制之一就是两个进程必须是相关联的进程。若是没有关系的进程间通信就要用命名管道。命名管道通常被称为FIFO。它作为特殊的设备文件存在于文件系统中。因此,在进程中可以使用open()和close()函数打开和关闭命名管道。 3.1 创建一个命名管道 · 命名管道可以从命令行上创建,命令行方法是使用下面这个命令: $ mkfifo filename· 也可以从程序里创建,相关函数: #include #include int mkfifo(const char* pathname, mode_t mode);该函数的参数pathname是一个文件的路径名,是创建的一个命名管道的文件名;参数mode是指文件的权限,文件权限取决于(mode&~umask)的值。 使用mkfifo()函数创建的命名管道文件与前面介绍的管道通信相似,只是它们创建方式不同。访问命名管道文件与访问文件系统中的其他文件一样,都是需要首先打开文件,然后对文件进行读写数据。如果在命名管道文件中读取数据时,并没有其他进程向命名管道文件中写入数据,则会出现进程阻塞状态;如果在写入数据的同时,没有进程从命名管道中读取数据,也会出现进程阻塞状态。 程序如下: #include #include #include #include #include #define FIFO "/root/process/hello" int main() { int fd; int pid; char r_msg[BUFSIZ]; if((pid = mkfifo(FIFO,0777))==-1) /*创建命名管道*/ { perror("create fifo channel failed!"); return 1; } else printf("create success!\n"); fd = open(FIFO, O_RDWR); /*打开命名管道*/ if(fd == -1) { perror("cannot open the FIFO"); return 1; } if(write(fd,"hello world", 12) == -1) /*写入消息*/ { perror("write data error!"); return 1; } else printf("write data success!\n"); if(read(fd, r_msg, BUFSIZ) == -1) /*读取消息*/ { perror("read error!"); return 1; } else printf("the receive data is: %s\n",r_msg); close(fd); /*关闭文件*/ return 0; }
|
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |