文档库 最新最全的文档下载
当前位置:文档库 › Linux进程间管道通信的研究

Linux进程间管道通信的研究

Linux进程间管道通信的研究
Linux进程间管道通信的研究

3 2007209220收到,2007211220改回

33 周 超,女,1976年生,在读硕士,讲师,1998年6月毕业于河南师范大学,研究方向:计算机软件,操作系统。

文章编号:100325850(2008)0120048203

Linux 进程间管道通信的研究

The Research on Inter -Process Pipe Communication under Linux

周 超 董军军

(焦作大学计算机系 焦作 454003)

【摘 要】对于多用户、多任务的操作系统,进程间的通信(Inter 2Process Communication ,IPC )是非常重要的,它是使整个系统得以有条不紊运作的基础。Linux 操作系统提供了多种IPC 机制,如信号、管道、信号量、消息队列、共享内存和套接字等,其中以管道通信最能体现Linux 平台的特色。为此,系统地分析了Linux 平台下的管道通信的实现机制,详细探讨了无名管道和命名管道的工作方式,并给出了相应的创建和使用的方法。【关键词】Linux ,进程,管道,文件

中图分类号:TP 301文献标识码:A

ABSTRACT The Inter 2Process Communication (IPC )is very important to the operating system of multiuser and multitask .It is the base of well working system .Linux provides IPC mechanism including siganals ,pipe ,semaphore ,shared 2memory and socket etc .Inter 2process pipe communication is feature of Linux .So this paper analyzes the mechanism of pipe communication under Linux platform systematically ,discusses the work mode of anonymous pipe and named pipe in detail ,and gives the corresponding

method for creating and using them .KEYWORDS Linux ,process ,pipe ,file

在进程之间进行通信的最简单方法是通过文件,其中一个进程写文件,而另一个进程读文件。这种方法简单易行,但容易造成内存空间和读文件时间的浪费,应用管道可克服这些缺点。管道是Linux 中最常见的IPC 机制,它实际上是在进程间开辟一个固定大小的缓冲区,需要发布信息的进程运行写操作,需要接收信息的进程运行读操作。管道是单向的字节流,它把一个进程的标准输出和另一个进程的标准输人连接在一起。由于发送进程和接收进程是通过管道进行通信的,又称管道通信。如下列Linux 命令:

ls 2l sort

这里建立了这样一个管道:获取ls 的输出,再将它作为sort 命令的输人。形象地说,就是数据沿着管道从左边流到了右边。

1 管道的实现机制

管道就是指用于连接一个读进程和一个写进程,以实现它们之间通信的共享文件,又称pipe 文件。Linux 中实现了两种管道,一种是无名管道,一种是命名管道。无名管道没有磁盘节点,它仅作为一个内存对象存在,用完后就销毁了。因为没有文件名和路径,也没有磁盘节点,因此无名管道没有显式的打开过程,实际上它是在创建时就自动打开的,并且生成内存inode 节点、dentry 目录项对象和两个文件结构对象(一个读操作、一个写操作),其内存对象和普通文件的一致,所

以读写操作使用的是同样的文件接口,当然读写函数是专用的。因为无名管道不能显式打开,因此只能由父子进程之间、兄弟进程之间或者其他有亲缘关系并且都继承了祖先进程的管道文件对象的两个进程间通信使用。命名管道是有文件名和磁盘i 节点的,因此可由任意两个或多个进程间通信使用,它的使用方法和普通文件类似,都遵循打开、读、写、关闭这样的过程,但是读写的内部实现和普通文件不同,而和无名管道一样。

2 无名管道

2.1 无名管道的工作方式

管道以先进先出方式保存一定数量的数据。使用

管道的时候一个进程从管道的一端写,另一个进程从管道的另一端读。在主进程中利用fork ()函数创建一个子进程,这样父子进程同时拥有对同一管道的读写句柄,因为管道没有提供锁定的保护机制,所以必须决定数据的流动方向,然后在相应进程中关闭不需要的句柄。这样,就可以使用read ()和write ()函数来对它进行读写操作了。使用无名管道进行进程间通信的步骤概述如下:

①创建所需的管道;②生成(多个)子进程;③关闭 复制文件描述符,使之与相应的管道末端相联系;

?84?(总50)

Linux 进程间管道通信的研究2008

年 

④关闭不需要的管道末端;

⑤进行通信活动;

⑥关闭所有剩余的打开文件描述符

⑦等待子进程结束。

由于read()函数和write()函数对管道操作自身带有阻塞作用,能够保证一个进程必须先进行写操作,然后另外的进程才能进行读操作,从而实现父子进程的同步。

2.2 无名管道的建立和使用

21211 管道的创建pipe函数

#include

int pipe(int fd[2])

函数的参数中有两个文件描述符:fd[0]用于管道的read端,fd[1]用于管道的write端。创建成功则返回值0,否则返回21值。

21212 写管道write函数

ret=write(fd[1],buf,n)

若管道已满,则被阻塞,直到管道另一端read将已进人管道的数据取走为止。

21213 读管道read函数

ret=read(fd[0],buf,n)

若管道为空,且写端文件描述字未关闭,则被阻塞。若管道写端已关闭,则返回0。

若管道不为空,分两种情况:(设管道中实际有m 个字节),如n>=m,则读m个;如果n

21214 关闭管道close函数

关闭写端则导致读端read调用返回0;关闭读端,则导致写端write调用返回21,errno被设为EPIPE,在写端write函数退出前,进程还会收到SIGPIPE信号(默认处理是终止进程,该信号可以被捕捉)。21215 文件描述符的复制dup2

int dup2(int fdl,int fd2);

复制文件描述符fdl到fd2。fd2可以是空闲的文件描述符,如果fd2是已打开文件,则关闭fd2;如果fd 1不是有效的描述符,则不关闭fd2,调用失败。

2.3 关于无名管道需要注意的几个问题

①管道是半双工方式,数据只能单向传输。如果要在两个进程之间相互传送数据,就要建立两条管道。

②pipe()调用必须在调用fork()以前进行,否则子进程将无法继承文件描述符。

③使用无名管道互相连接的任意进程必须位于一个相关的进程家族里。因为管道必须受到内核的限制,所以如果进程没有在管道创建者的家族里面,则该进程将无法访问管道。3 命名管道

在Linux系统中,可以识别命名管道文件。例如:

$ls2l filename

prw2r22r22l root root0sep2719:40filename

filename文件名后跟着一个“ ”符号表明该文件是管道文件。

3.1 命名管道的工作方式

无名管道应用的一个重大限制是只能用于具有亲缘关系的进程间通信,在命名管道提出后,该限制得到了克服。命名管道提供一个路径名与之关联,以FIFO 的文件形式存在于文件系统中。这样,即使与FIFO的创建进程不存在亲缘关系的进程,只要可以访问该路径,就能够彼此通过FIFO相互通信。因此,通过FIFO,不相关的进程也能交换数据。FI FO管道的打开方式与普通管道有所不同,普通管道包括两个文件数据结构:对应的VFS索引节点以及共享数据页,在进程每次运行时都会创建一次,而FIFO是一直存在的,需要用户打开和关闭。Linux必须处理读进程先于写进程打开管道、读进程在写进程写入数据之前读入这两种情况。除此之外,FIFO管道的使用方式与普通管道完全相同,都使用相同的数据结构和操作。

3.2 FIFO文件的创建

命名管道的创建有两种常见的方法:在shell提示符下使用mknod命令或在程序中使用mknod()系统调用。

31211 shell命令行方式

shell命令行方式如下

$mknod filename p

$mkfifo a=r w filename

这两个命令行均可创建FIFO文件filename。mkfifo提供了直接改变文件读写权限的功能。mknod 创建的文件通过chmod可以改变权限。其中参数p表示所建立的节点,即特殊文件的类型为命名管道。31212 函数调用

mknod()是一般的设备文件创建函数:

#include

#include

int mknod(const char3filename,mode t mode,dev t dev)

其中,filename是被创建文件的名称。mode表示将在该文件上设置的权限位和将被创建的文件类型(此情况下为S FI FO);dev是创建设备文件时使用的值。

mkfifo()函数专门用于创建FIFO。

#include

?

94

?

 第21卷 第1期电脑开发与应用(总51

)

#include

int mkfifo(const char3filename,mode t mode)

此两个函数均调用成功后返回0值,否则返回21。

FIFO文件的读空管道和写满管道的操作方式与无名管道相同,并且用fcntl()设置O NONBLOCK 标志时,将引起read()调用和write()调用立即返回。在它们已被阻塞的情况下,带回一个以EGAIN错误信息。

FIFO可以被许多进程同时访问,如果多个进程在写一个管道时,在管道可容纳的范围内,系统将保证各进程所写的数据是分开的。因此,在多个进程的读 写应用中FIFO非常有用。

3.3 SIGPIPE信号

需要注意的是,管道必须有人读并有人写。如果某个进程企图往管道中写数据,而没有进程去读该管道,则内核将向该进程发送SIGPIPE信号。当在管道操作中涉及到两个以上的进程时,这个信号是非常必要的。

4 管道的不足

管道提供了从一种进程向另一种进程传输数据的有效方法,但是,管道还是存在一些不足:

①因为读数据的同时也将数据从管道移去,因此管道不能用来对多个接受者广播数据。

②如果一个管道有多个读进程,那么写进程不能发送数据到指定的读进程。同样,如果有多个写进程,那么没有方法来判别是它们中的哪一个发送的数据。

5 结束语

Linux平台下进程间通信的方式很多,其中以管道通信最能体现Linux平台的特色。本文详细讨论了Linux平台下的管道通信,其中无名管道可用于具有亲缘关系进程间的通信;命名管道除具有无名管道所具有的功能外,它还允许无亲缘关系进程间的通信。管道常用于两个方面:①在shell中时常会用到管道,在这种应用方式下,管道的创建对于用户来说是透明的;

②用于具有亲缘关系的进程间通信,用户自己创建管道,并完成读写操作。

参考文献

[1]魏永明,杨飞月,吴澳霖.Linux实用技术[M].北京:

电子工业出版杜,1999.

[2][美]David A Rusling著.朱 珂译.Linux编程白皮

书[M].北京:机械工业出版社,2000.

[3]陈莉君.Linux操作系统内核分析[M].北京:人民邮

电出版社,2000.

[4]张银福,陈曙晖,赵振宇.Linux网络应用技术[M].长

沙:国防科学技术大学,1999.

(上接第47页)

应用层包含有多个协议,常见的有FTP(文件传输协议)、Telnet(远程登录协议)、SMTP(简单邮件传输协议)、HTTP(超文本传输协议)等。具体使用哪个协议,要根据嵌入式系统实现的功能来确定。目前嵌入式Web系统中多数是实现浏览器访问,因此这里以HTTP协议为例进行分析。

HTTP是应用层的一个面向对象的协议,它规定了Web服务器与浏览器之间的信息传递规范,它建立在TCP协议基础之上,依赖TCP来确保传输的正确性。可以利用该协议传输简单的文本、超文本、声音信号、图像以及任何在Internet上可以访问的信息。

HTTP协议的机制比较复杂,对处理器的运算能力和存储能力要求较高。完整的HTTP协议支持GET、POST、HEAD、OPTIONS、PUT、DELETE、TRACE等七种请求方法,在嵌入式系统中考虑到服务器只起到提供信息浏览的作用,因此可以只实现GET请求方法,以此降低HTTP的复杂度。当有HTTP数据报文到达时,服务器首先解析是否为GET 请求,如果不是,则不予处理,如果是则进一步解析所请求的页面网址,并封装应答数据报文进行回送。需要注意的是,应使响应数据封装在一个数据包中传输,避免分包传输。

3 结束语

本文对嵌入式Internet系统中TCP IP协议栈的实现进行了研究与分析,针对每一层的具体协议,提出了设计方法和精简方案。由于嵌入式设备自身资源的限制,使得TCP IP协议栈的实现上存在功能简单、安全性不高等问题。但是随着嵌入式硬件设备和Internet技术的不断发展,嵌入式TCP IP协议栈的实现也将会越来越完善,应用范围也会越来越广泛。

参考文献

[1]李素侠,段友祥.嵌入式TCP IP协议的分析与研究

[J].微计算机信息,2005(7):52253.

[2]Stevens W R.TCP IP译解卷1:协议[M].北京:机械

工业出版社,2000.

[3]汤子瀛.计算机网络技术及其应用[M].成都:电子科

技大学出版社,1999.

[4]M Tim Jone.嵌入式系统TCP IP应用层协议[M].北

京:电子工业出版社,2003.

?

05

?(总52)Linux进程间管道通信的研究2008

年 

Linux系统编程实验六进程间通信

实验六:进程间通信 实验目的: 学会进程间通信方式:无名管道,有名管道,信号,消息队列, 实验要求: (一)在父进程中创建一无名管道,并创建子进程来读该管道,父进程来写该管道(二)在进程中为SIGBUS注册处理函数,并向该进程发送SIGBUS信号(三)创建一消息队列,实现向队列中存放数据和读取数据 实验器材: 软件:安装了Linux的vmware虚拟机 硬件:PC机一台 实验步骤: (一)无名管道的使用 1、编写实验代码pipe_rw.c #include #include #include #include #include #include int main() { int pipe_fd[2];//管道返回读写文件描述符 pid_t pid; char buf_r[100]; char* p_wbuf; int r_num; memset(buf_r,0,sizeof(buf_r));//将buf_r初始化 char str1[]=”parent write1 “holle””; char str2[]=”parent write2 “pipe”\n”; r_num=30; /*创建管道*/ if(pipe(pipe_fd)<0) { printf("pipe create error\n"); return -1; } /*创建子进程*/ if((pid=fork())==0) //子进程执行代码 {

//1、子进程先关闭了管道的写端 close(pipe_fd[1]); //2、让父进程先运行,这样父进程先写子进程才有内容读sleep(2); //3、读取管道的读端,并输出数据 if(read(pipe_fd[0],buf_r, r_num)<0) { printf(“read error!”); exit(-1); } printf(“%s\n”,buf_r); //4、关闭管道的读端,并退出 close(pipe_fd[1]); } else if(pid>0) //父进程执行代码 { //1、父进程先关闭了管道的读端 close(pipe_fd[0]); //2、向管道写入字符串数据 p_wbuf=&str1; write(pipe_fd[1],p_wbuf,sizof(p_wbuf)); p_wbuf=&str2; write(pipe_fd[1],p_wbuf,sizof(p_wbuf)); //3、关闭写端,并等待子进程结束后退出 close(pipe_fd[1]); } return 0; } /*********************** #include #include #include #include #include #include int main() { int pipe_fd[2];//管道返回读写文件描述符 pid_t pid; char buf_r[100]; char* p_wbuf; int r_num;

Windows进程间各种通信方式浅谈

Windows进程间各种通信方式浅谈 1、Windows进程间通信的各种方法 进程是装入内存并准备执行的程序,每个进程都有私有的虚拟地址空间,由代码、数据以及它可利用的系统资源(如文件、管道等)组成。 多进程/多线程是Windows操作系统的一个基本特征。Microsoft Win32应用编程接口(Application Programming Interface, API) 提供了大量支持应用程序间数据共享和交换的机制,这些机制行使的活动称为进程间通信(InterProcess Communication, IPC),进程通信就是指不同进程间进行数据共享和数据交换。 正因为使用Win32 API进行进程通信方式有多种,如何选择恰当的通信方式就成为应用开发中的一个重要问题, 下面本文将对Win32中进程通信的几种方法加以分析和比较。 2、进程通信方法 2.1 文件映射 文件映射(Memory-Mapped Files)能使进程把文件内容当作进程地址区间一块内存那样来对待。因此,进程不必使用文件I/O操作,只需简单的指针操作就可读取和修改文件的内容。 Win32 API允许多个进程访问同一文件映射对象,各个进程在它自己的地址空间里接收内存的指针。通过使用这些指针,不同进程就可以读或修改文件的内容,实现了对文件中数据的共享。 应用程序有三种方法来使多个进程共享一个文件映射对象。 (1)继承:第一个进程建立文件映射对象,它的子进程继承该对象的句柄。 (2)命名文件映射:第一个进程在建立文件映射对象时可以给该对象指定一个名字(可与文件名不同)。第二个进程可通过这个名字打开此文件映射对象。另外,第一个进程也可以通过一些其它IPC机制(有名管道、邮件槽等)把名字传给第二个进程。 (3)句柄复制:第一个进程建立文件映射对象,然后通过其它IPC机制(有名管道、

Linux进程间通信(2)实验报告

实验六:Linux进程间通信(2)(4课时) 实验目的: 理解进程通信原理;掌握进程中信号量、共享内存、消息队列相关的函数的使用。实验原理: Linux下进程通信相关函数除上次实验所用的几个还有: 信号量 信号量又称为信号灯,它是用来协调不同进程间的数据对象的,而最主要的应用是前一节的共享内存方式的进程间通信。要调用的第一个函数是semget,用以获得一个信号量ID。 int semget(key_t key, int nsems, int flag); key是IPC结构的关键字,flag将来决定是创建新的信号量集合,还是引用一个现有的信号量集合。nsems是该集合中的信号量数。如果是创建新集合(一般在服务器中),则必须指定nsems;如果是引用一个现有的信号量集合(一般在客户机中)则将nsems指定为0。 semctl函数用来对信号量进行操作。 int semctl(int semid, int semnum, int cmd, union semun arg); 不同的操作是通过cmd参数来实现的,在头文件sem.h中定义了7种不同的操作,实际编程时可以参照使用。 semop函数自动执行信号量集合上的操作数组。 int semop(int semid, struct sembuf semoparray[], size_t nops); semoparray是一个指针,它指向一个信号量操作数组。nops规定该数组中操作的数量。 ftok原型如下: key_t ftok( char * fname, int id ) fname就是指定的文件名(该文件必须是存在而且可以访问的),id是子序号,虽然为int,但是只有8个比特被使用(0-255)。 当成功执行的时候,一个key_t值将会被返回,否则-1 被返回。 共享内存 共享内存是运行在同一台机器上的进程间通信最快的方式,因为数据不需要在不同的进程间复制。通常由一个进程创建一块共享内存区,其余进程对这块内存区进行读写。首先要用的函数是shmget,它获得一个共享存储标识符。 #include #include #include int shmget(key_t key, int size, int flag); 当共享内存创建后,其余进程可以调用shmat()将其连接到自身的地址空间中。 void *shmat(int shmid, void *addr, int flag); shmid为shmget函数返回的共享存储标识符,addr和flag参数决定了以什么方式来确定连接的地址,函数的返回值即是该进程数据段所连接的实际地

进程间通信的四种方式

一、剪贴板 1、基础知识 剪贴板实际上是系统维护管理的一块内存区域,当在一个进程中复制数据时,是将这个数据放到该块内存区域中,当在另一个进程中粘贴数据时,是从该内存区域中取出数据。 2、函数说明: (1)、BOOL OpenClipboard( ) CWnd类的OpenClipboard函数用于打开剪贴板。若打开剪贴板成功,则返回非0值。若其他程序或当前窗口已经打开了剪贴板,则该函数返回0值,表示打开失败。若某个程序已经打开了剪贴板,则其他应用程序将不能修改剪贴板,直到前者调用了CloseClipboard函数。 (2)、BOOL EmptyClipboard(void) EmptyClipboard函数将清空剪贴板,并释放剪贴板中数据的句柄,然后将剪贴板的所有权分配给当前打开剪贴板的窗口。 (3)、HANDLE SetClipboardData(UINT uFormat, HANDLE hMem) SetClipboardData函数是以指定的剪贴板格式向剪贴板上放置数据。uFormat指定剪贴板格式,这个格式可以是已注册的格式,或是任一种标准的剪贴板格式。CF_TEXT表示文本格式,表示每行数据以回车换行(0x0a0x0d)终止,空字符作为数据的结尾。hMem指定具有指定格式的数据的句柄。hMem参数可以是NULL,指示采用延迟提交技术,则该程序必须处理WM_RENDERFORMA T和WM_RENDERALLFORMATS消息。应用程序在调用SetClipboardData函数之后,就拥有了hMem参数所标识的数据对象,该应用程序可以读取该数据对象,但在应用程序调用CloseClipboard函数之前,它不能释放该对象的句柄,或者锁定这个句柄。若hMem标识了一个内存对象,那么这个对象必须是利用GMEM_MOVEABLE标志调用GlobalAlloc函数为其分配内存。 注意:调用SetClipboardData函数的程序必须是剪贴板的拥有者,且在这之前已经打开了剪贴板。 延迟提交技术:当一个提供数据的进程创建了剪贴板数据之后,直到其他进程获取剪贴板数据之前,这些数据都要占据内存空间。若在剪贴板上放置的数据过大,就会浪费内存空间,降低对资源的利用率。为了避免这种浪费,就可以采用延迟提交计数,也就是由数据提供进程先提供一个指定格式的空剪贴板数据块,即把SetClipboardData函数的hMem参数设置为NULL。当需要获取数据的进程想要从剪贴板上得到数据时,操作系统会向数据提供进程发送WM_RENDERFORMA T消息,而数据提供进程可以响应这个消息,并在此消息的响应函数中,再一次调用SetClipboardData函数,将实际的数据放到剪贴板上。当再次调用SetClipboardData函数时,就不再需要调用OpenClipboard函数,也不再需要调用EmptyClipboard函数。也就是说,为了提高资源利用率,避免浪费内存空间,可以采用延迟提交技术。第一次调用SetClipboardData函数时,将其hMem参数设置为NULL,在剪贴板上以指定的剪贴板格式放置一个空剪贴板数据块。然后直到有其他进程需要数据或自身进程需要终止运行时再次调用SetClipboardData函数,这时才真正提交数据。 (4)、HGLOBAL GlobalAlloc( UINT uFlags,SIZE_T dwBytes); GlobalAlloc函数从堆上分配指定数目的字节。uFlags是一个标记,用来指定分配内存的方式,uFlags为0,则该标记就是默认的GMEM_FIXED。dwBytes指定分配的字节数。

Linux进程通信实验报告

Linux进程通信实验报告 一、实验目的和要求 1.进一步了解对进程控制的系统调用方法。 2.通过进程通信设计达到了解UNIX或Linux系统中进程通信的基本原理。 二、实验内容和原理 1.实验编程,编写程序实现进程的管道通信(设定程序名为pipe.c)。使 用系统调用pipe()建立一条管道线。而父进程从则从管道中读出来自 于两个子进程的信息,显示在屏幕上。要求父进程先接受子进程P1 发来的消息,然后再接受子进程P2发来的消息。 2.可选实验,编制一段程序,使其实现进程的软中断通信(设定程序名为 softint.c)。使用系统调用fork()创建两个子进程,再用系统调用 signal()让父进程捕捉键盘上来的中断信号(即按Del键),当父进程 接受这两个软中断的其中一个后,父进程用系统调用kill()向两个子 进程分别发送整数值为16和17的软中断信号,子进程获得对应软中 断信号后分别输出相应信息后终止。 三、实验环境 一台安装了Red Hat Linux 9操作系统的计算机。 四、实验操作方法和步骤 进入Linux操作系统,利用vi编辑器将程序源代码输入并保存好,然后 打开终端对程序进行编译运行。 五、实验中遇到的问题及解决 六、实验结果及分析 基本实验 可选实验

七、源代码 Pipe.c #include"stdio.h" #include"unistd.h" main(){ int i,j,fd[2]; char S[100]; pipe(fd); if(i=fork==0){ sprintf(S,"child process 1 is sending a message \n"); write(fd[1],S,50); sleep(3); return; } if(j=fork()==0){ sprintf(S,"child process 2 is sending a message \n"); write(fd[1],S,50); sleep(3); return;

进程间通信方式比较

进程间的通信方式: 1.管道(pipe)及有名管道(named pipe): 管道可用于具有亲缘关系进程间的通信,有名管道除了具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。 2.信号(signal): 信号是在软件层次上对中断机制的一种模拟,它是比较复杂的通信方式,用于通知进程有某事件发生,一个进程收到一个信号与处理器收到一个中断请求效果上可以说是一致得。 3.消息队列(message queue): 消息队列是消息的链接表,它克服了上两种通信方式中信号量有限的缺点,具有写权限得进程可以按照一定得规则向消息队列中添加新信息;对消息队列有读权限得进程则可以从消息队列中读取信息。 消息缓冲通信技术是由Hansen首先提出的,其基本思想是:根据”生产者-消费者”原理,利用内存中公用消息缓冲区实现进程之间的信息交换. 内存中开辟了若干消息缓冲区,用以存放消息.每当一个进程向另一个进程发送消息时,便申请一个消息缓冲区,并把已准备好的消息送到缓冲区,然后把该消息缓冲区插入到接收进程的消息队列中,最后通知接收进程.接收进程收到发送里程发来的通知后,从本进程的消息队列中摘下一消息缓冲区,取出所需的信息,然后把消息缓冲区不定期给系统.系统负责管理公用消息缓冲区以及消息的传递. 一个进程可以给若干个进程发送消息,反之,一个进程可以接收不同进程发来的消息.显然,进程中关于消息队列的操作是临界区.当发送进程正往接收进程的消息队列中添加一条消息时,接收进程不能同时从该消息队列中到出消息:反之也一样. 消息缓冲区通信机制包含以下列内容:

(1) 消息缓冲区,这是一个由以下几项组成的数据结构: 1、消息长度 2、消息正文 3、发送者 4、消息队列指针 (2)消息队列首指针m-q,一般保存在PCB中。 (1)互斥信号量m-mutex,初值为1,用于互斥访问消息队列,在PCB中设置。 (2)同步信号量m-syn,初值为0,用于消息计数,在PCB中设置。(3)发送消息原语send (4)接收消息原语receive(a) 4.共享内存(shared memory): 可以说这是最有用的进程间通信方式。它使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据得更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。 这种通信模式需要解决两个问题:第一个问题是怎样提供共享内存;第二个是公共内存的互斥关系则是程序开发人员的责任。 5.信号量(semaphore): 主要作为进程之间及同一种进程的不同线程之间得同步和互斥手段。 6.套接字(socket); 这是一种更为一般得进程间通信机制,它可用于网络中不同机器之间的进程间通信,应用非常广泛。 https://www.wendangku.net/doc/f912589875.html,/eroswang/archive/2007/09/04/1772350.aspx linux下的进程间通信-详解

linux进程间通讯的几种方式的特点和优缺点

1. # 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。 # 有名管道(named pipe) :有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。 # 信号量( semophore ) :信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。 # 消息队列( message queue ) :消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。 # 信号( sinal ) :信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。#共享内存( shared memory):共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。 # 套接字( socket ) :套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。 管道的主要局限性正体现在它的特点上: 只支持单向数据流; 只能用于具有亲缘关系的进程之间; 没有名字; 管道的缓冲区是有限的(管道制存在于内存中,在管道创建时,为缓冲区分配一个页面大小);管道所传送的是无格式字节流,这就要求管道的读出方和写入方必须事先约定好数据的格式,比如多少字节算作一个消息(或命令、或记录)等等; 2. 用于进程间通讯(IPC)的四种不同技术: 1. 消息传递(管道,FIFO,posix和system v消息队列) 2. 同步(互斥锁,条件变量,读写锁,文件和记录锁,Posix和System V信号灯) 3. 共享内存区(匿名共享内存区,有名Posix共享内存区,有名System V共享内存区) 4. 过程调用(Solaris门,Sun RPC) 消息队列和过程调用往往单独使用,也就是说它们通常提供了自己的同步机制.相反,共享内存区

进程间的通信

# 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。 # 有名管道(named pipe) :有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。 # 信号量( semophore ) :信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。 # 消息队列( message queue ) :消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。 # 信号( sinal ) :信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。# 共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。 # 套接字( socket ) :套接口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。 windows进程通信的几种方式(转) 2008-10-13 16:47 1 文件映射 文件映射(Memory-Mapped Files)能使进程把文件内容当作进程地址区间一块内存那样来对待。因此,进程不必使用文件I/O操作,只需简单的指针操作就可读取和修改文件的内容。 Win32 API允许多个进程访问同一文件映射对象,各个进程在它自己的地址空间里接收内存的指针。通过使用这些指针,不同进程就可以读或修改文件的内容,实现了对文件中数据的共享。 应用程序有三种方法来使多个进程共享一个文件映射对象。 (1)继承:第一个进程建立文件映射对象,它的子进程继承该对象的句柄。 (2)命名文件映射:第一个进程在建立文件映射对象时可以给该对象指定一个名字(可与文件名不同)。第二个进程可通过这个名字打开此文件映射对象。另外,第一个进程也可以通过一些其它IPC机制(有名管道、邮件槽等)把名字传给第二个进程。 (3)句柄复制:第一个进程建立文件映射对象,然后通过其它IPC机制(有名管道、邮件槽等)把对象句柄传递给第二个进程。第二个进程复制该句柄就取得对该文件映射对象的访问权限。 文件映射是在多个进程间共享数据的非常有效方法,有较好的安全性。但文件映射只能用于本地机器的进程之间,不能用于网络中,而开发者还必须控制进程间的同步。 2 共享内存 Win32 API中共享内存(Shared Memory)实际就是文件映射的一种特殊情况。进程在创建文件映射对象时用0xFFFFFFFF来代替文件句柄(HANDLE),就表示了对应的文件映射对象是从操作系统页面文件访问内存,其它进程打开该文件映射

Linux下的进程间通信-详解

Linux下的进程间通信-详解 详细的讲述进程间通信在这里绝对是不可能的事情,而且笔者很难有信心说自己对这一部分内容的认识达到了什么样的地步,所以在这一节的开头首先向大家推荐著 名作者Richard Stevens的著名作品:《Advanced Programming in the UNIX Environment》,它的中文译本《UNIX环境高级编程》已有机械工业出版社出版,原文精彩,译文同样地道,如果你的确对在Linux下编程有浓 厚的兴趣,那么赶紧将这本书摆到你的书桌上或计算机旁边来。说这么多实在是难抑心中的景仰之情,言归正传,在这一节里,我们将介绍进程间通信最最初步和最 最简单的一些知识和概念。 首先,进程间通信至少可以通过传送打开文件来实现,不同的进程通过一个或多个文件来传递信息,事实上,在很多应用系统里,都使用了这种方法。但一般说来, 进程间通信(IPC:InterProcess Communication)不包括这种似乎比较低级的通信方法。Unix系统中实现进程间通信的方法很多,而且不幸的是,极少方法能在所有的Unix系 统中进行移植(唯一一种是半双工的管道,这也是最原始的一种通信方式)。而Linux作为一种新兴的操作系统,几乎支持所有的Unix下常用的进程间通信 方法:管道、消息队列、共享内存、信号量、套接口等等。下面我们将逐一介绍。 2.3.1 管道 管道是进程间通信中最古老的方式,它包括无名管道和有名管道两种,前者用于父进程和子进程间的通信,后者用于运行于同一台机器上的任意两个进程间的通信。 无名管道由pipe()函数创建: #include int pipe(int filedis[2]); 参数filedis返回两个文件描述符:filedes[0]为读而打开,filedes[1]为写而打开。filedes[1]的输出是filedes[0]的输入。下面的例子示范了如何在父进程和子进程间实现通信。 #define INPUT 0 #define OUTPUT 1 void main() { int file_descriptors[2]; /*定义子进程号 */ pid_t pid; char buf[256]; int returned_count; /*创建无名管道*/ pipe(file_descriptors); /*创建子进程*/ if((pid = fork()) == -1) { printf("Error in fork\n"); exit(1); } /*执行子进程*/ if(pid == 0) { printf("in the spawned (child) process...\n"); /*子进程向父进程写数据,关闭管道的读端*/ close(file_descriptors[INPUT]); write(file_descriptors[OUTPUT], "test data", strlen("test data"));

04--Linux系统编程-进程间通信

IPC方法 Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信(IPC,InterProcess Communication)。 在进程间完成数据传递需要借助操作系统提供特殊的方法,如:文件、管道、信号、共享内存、消息队列、套接字、命名管道等。随着计算机的蓬勃发展,一些方法由于自身设计缺陷被淘汰或者弃用。现今常用的进程间通信方式有: ①管道(使用最简单) ②信号(开销最小) ③共享映射区(无血缘关系) ④本地套接字(最稳定) 管道 管道的概念: 管道是一种最基本的IPC机制,作用于有血缘关系的进程之间,完成数据传递。调用pipe系统函数即可创建一个管道。有如下特质: 1. 其本质是一个伪文件(实为内核缓冲区) 2.由两个文件描述符引用,一个表示读端,一个表示写端。 3. 规定数据从管道的写端流入管道,从读端流出。 管道的原理: 管道实为内核使用环形队列机制,借助内核缓冲区(4k)实现。 管道的局限性: ①数据自己读不能自己写。 ②数据一旦被读走,便不在管道中存在,不可反复读取。 ③由于管道采用半双工通信方式。因此,数据只能在一个方向上流动。 ④只能在有公共祖先的进程间使用管道。

常见的通信方式有,单工通信、半双工通信、全双工通信。 pipe函数 创建管道 int pipe(int pipefd[2]); 成功:0;失败:-1,设置errno 函数调用成功返回r/w两个文件描述符。无需open,但需手动close。规定:fd[0] →r;fd[1] →w,就像0对应标准输入,1对应标准输出一样。向管道文件读写数据其实是在读写内核缓冲区。 管道创建成功以后,创建该管道的进程(父进程)同时掌握着管道的读端和写端。如何实现父子进程间通信呢?通常可以采用如下步骤: 1.父进程调用pipe函数创建管道,得到两个文件描述符fd[0]、fd[1]指向管道的读端和写端。 2.父进程调用fork创建子进程,那么子进程也有两个文件描述符指向同一管道。 3.父进程关闭管道读端,子进程关闭管道写端。父进程可以向管道中写入数据,子进程将管道中的数据读出。由于管道是利用环形队列实现的,数据从写端流入管道,从读端流出,这样就实现了进程间通信。 练习:父子进程使用管道通信,父写入字符串,子进程读出并,打印到屏幕。【pipe.c】 思考:为甚么,程序中没有使用sleep函数,但依然能保证子进程运行时一定会读到数据呢? 管道的读写行为 使用管道需要注意以下4种特殊情况(假设都是阻塞I/O操作,没有设置O_NONBLOCK标志): 1.如果所有指向管道写端的文件描述符都关闭了(管道写端引用计数为0),而仍然有进程从管道的读端读数据,那么管道中剩余的数据都被读取后,再次read会返回0,就像读到文件末尾一样。

Linux进程间通信程序设计

计算机与信息技术学院设计性实验报告 一、实验目的 (1)理解进程概念; (2)理解并掌握多进程开发模式; (3)理解并掌握Linux平台进程间数据的传送方法。 二、总体设计 (1)实验内容:编写程序实现进程的管道通信。用系统调用pipe( )建立一管道,创建两个二个子进程P1和P2分别向管道各写一句话: Message from child P1! Message from child P2! 父进程从管道中读出二个来自子进程的信息并显示。 (2)设计原理: 所谓管道,是指能够连接一个写进程和一个读进程、并允许它们进行通信的一个共享文件,又称为pipe文件。由写进程从管道的写入端(句柄1)将数据写入管道,而读进程则从管道的读出端(句柄0)读出数据。 通过管道的信息流 三、实验步骤: #include

#include #include #include # include #define BUFSIZE 100 int pid1,pid2; int main() { int fd[2]; char buf_out [BUFSIZE], buf_in [BUFSIZE]; if (pipe(fd) < 0) { printf("pipe error\n"); exit(1); } /*创建一个管道*/ if ((pid1 = fork()) < 0) /*创建子进程1*/ { printf("fork1 failure\n"); exit(1); } else if (pid1 == 0) { lockf(fd[1],1,0); strcpy(buf_out," Message from child P1!"); /*把串放入数组buf_out中*/ write(fd[1],buf_out,BUFSIZE); /*向管道写长为BUFSIZE字节的串*/ sleep(5); /*自我阻塞5秒*/ lockf(fd[1],0,0); exit(0); } else { while((pid2=fork( ))==-1); /*创建子进程2*/ if(pid2==0) { lockf(fd[1],1,0); /*互斥*/ sprintf(buf_out,"Message from child %d!",getpid()); write(fd[1], buf_out,BUFSIZE); sleep(5); lockf(fd[1],0,0); exit(0); } else { wait(0); /*同步*/ read(fd[0], buf_in,BUFSIZE); /*从管道中读长为BUFSIZE字节的串*/ printf("%s\n", buf_in); wait(0); read(fd[0], buf_in,BUFSIZE); printf("%s\n", buf_in); exit(0); } }

进程间通信的几种方式

进程间通信的几种方式 2009-06-19 23:28 (1)管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。 (2)命名管道(named pipe):命名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo来创建。 (3)信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外,还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用sigaction函数重新实现了signal函数)。 (4)消息(Message)队列:消息队列是消息的链接表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺 (5)共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。 (6)内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。 (7)信号量(semaphore):主要作为进程间以及同一进程不同线程之间的同步手段。 (8)套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的,但现在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字

linux管道通信(C语言)

Linux环境中管道通信的实现 ?摘要Linux系统提供了丰富的进程通信手段,如信号、信号灯、管道、共享内存、消息队列等,能有效地完成多个进程间的信息共享和数据交换。本文主要设 计了Linux环境中的管道通信,并给出了利用该技术制作程序运行进程通信的实 例。 ?关键词管道;进程通信;IPC;Motif;进程条 1 引言 Linux系统提供了丰富的进程通信手段,如信号、信号灯、管道、共享内存、消息队列等,能有效地完成多个进程间的信息共享和数据交换。管道作为最早的进程间通信机制之一,可以在进程之间提供简单的数据交换和通信功能。 2 管道技术简介 2.1 管道的概念及特点 管道分为无名管道和有名管道两种。无名管道可用于具有亲缘关系进程间的通信,如父子进程、兄弟进程。有名管道克服了管道没有名字的限制,允许无亲缘关系进程间的通信。本文应用的是无名管道通信机制。 管道具有以下特点: (1)管道是半双工的,数据只能单向流动;需要相互通信时,就要建立两个管道。 (2)只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程,有名管道则突破了这一限制)。 (3)单独构成一种独立的文件系统,并且只存在于内存中。 (4)数据的读出和写入都是单向的:一个进程向管道中写的数据被管道另一端的进程读出。写入的数据每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。 2.2 管道的创建 #include int pipe(int fd[2]) 该函数是Linux的一个系统调用,其创建的管道两端处于一个进程中间。要用其实现父子进程之间的通信则需要在由pipe()创建管道后,再由系统调用fork创建一个新的子进程,然后通过管道在这两个进程间传送数据,实现进程间的通信(同样,不是父子关系和两个进程,只要两个进程中存在亲缘关系

实验三2_Linux进程间通信

实验三2_Linux进程间通信 实验三 Linux进程间通信 一、实验目的 熟悉Linux下进程间通信机制,能够使用系统提供的各种通信机制实现并发进程间的数据交换。 二、实验题目 分别使用Linux下的共享存储区、消息、管道等通信机制,编程实现并发进程之间的相互通信。 三、背景材料 (一)需要用到的系统调用 实验可能需要用到的主要系统调用和库函数在下面列出,详细的使用方法说明通过“man 2 系统调用名”或者“man 3 函数名”命令获取。 fork() 创建一个子进程,通过返回值区分是在父进程还是子进程中执行; wait() 等待子进程执行完成; getpid() 获取当前进程id; shmget() 建立一个共享存储区; shmctl() 操纵一个共享存储区; shmat() 把一个共享存储区附接到进程内存空间; shmdt() 把一个已经附接的共享存储区从进程内存空间断开; msgget() 建立一个消息队列; msgctl() 操纵一个消息队列; msgsnd() 发送消息; msgrcv() 接收消息;

signal() 设置对信号的处理方式或处理过程; pipe() 打开管道; lockf() 锁定一个文件。 (二)使用共享存储区的示例程序 下面程序主要用来演示共享存储区的使用方法:首先要使用shmget得到共享存储区句柄(可以新建或连接已有的共享存储区,以关键字标识),然后使用shmat挂接到进程的存储空间(这样才能够访问),当使用完后,使用shmctl释放(shmctl 还可以完成一些其他功能)。这种使用逻辑也适用于消息和信号量。示例程序代码如下: #include #include #include #include #include int main(void) { int x, shmid; int *shmptr; if((shmid=shmget(IPC_PRIVATE, sizeof(int), IPC_CREAT|0666)) < 0) printf("shmget error"), exit(1); //函数原型int shmget(key_t key,int size,int shmflg); 函数用于创建(或者获取)一 key键值指定的共享内存对象,返回该对象的系统标识符:shmid;size 是创个由

进程间通讯

全国嵌入式人才培训基地
4. 进程间通信 上一页 第 30 章 进程 下一页
4. 进程间通信
请点评
每个进程各自有不同的用户地址空间, 任何一个进程的全局变量在另一个进程中 都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区, 进程 2 再从内核缓冲区把数据读走, 进程 1 把数据从用户空间拷到内核缓冲区, 内核提供的这种机制称为进程间通信(IPC,InterProcess Communication)。 如下图所示。 图 30.6. 进程间通信
4.1. 管道 请点评
管道是一种最基本的 IPC 机制,由 pipe 函数创建:
#include
int pipe(int filedes[2]);
调用 pipe 函数时在内核中开辟一块缓冲区(称为管道)用于通信,它有一个读 端一个写端, 然后通过 filedes 参数传出给用户程序两个文件描述符, filedes[0] 指向管道的读端,filedes[1]指向管道的写端(很好记,就像 0 是标准输入 1 是标准输出一样)。所以管道在用户程序看起来就像一个打开的文件,通过 read(filedes[0]);或者 write(filedes[1]);向这个文件读写数据其实是在读 写内核缓冲区。pipe 函数调用成功返回 0,调用失败返回-1。

开辟了管道之后如何实现两个进程间的通信呢?比如可以按下面的步骤通信。 图 30.7. 管道
得到两个文件描述符指向管道的两端。 1. 父进程调用 pipe 开辟管道, 2. 父进程调用 fork 创建子进程,那么子进程也有两个文件描述符指 向同一管道。 3. 父进程关闭管道读端,子进程关闭管道写端。父进程可以往管道里 写,子进程可以从管道里读,管道是用环形队列实现的,数据从写 端流入从读端流出,这样就实现了进程间通信。 例 30.7. 管道

操作系统课程设计:Linux系统管理实践与进程通信实现

操作系统课程设计:Linux系统管理实践与进程通信实现

操作系统课程设计——Linux系统管理实践与进程通信实现 班级网络10 学号 31006100 姓名 YHD 指导老师詹永照

二零一三年一月八号 一、设计内容 1、Linux系统的熟悉与常用操作命令的掌握。 2、Linux环境下进程通信的实现。(实现父母子女放水果吃水果的同步互斥问题,爸爸放苹果,女儿专等吃苹果,妈妈放橘子,儿子专等吃橘子,盘子即为缓冲区,大小为5。) 二、Linux环境介绍 1、Linux的由来与发展 Linux是一种可以在PC机上执行的类似UNIX的操作系统,是一个完全免费的操作系统。1991年,芬兰学生Linux Torvalds开发了这个操作系统的核心部分,因为是Linux改良的minix系统,故称之为Linux。 2、Linux的优点 (1)Linux具备UNIX系统的全部优点 Linux是一套PC版的UNIX系统,相对于Windows是一个十分稳定的系统,安全性好。 (2)良好的网络环境 Linux与UNIX一样,是以网络环境为基础的操作系统,具备完整的网络功能,提供在Internet或Intranet的邮件,FTP,www等各种服务。 (3)免费的资源 Linux免费的资源和公开的源代码方便了对操作系统的深入了解,给编程爱好者提供更大的发挥空间。 3、Linux的特点 1)全面的多任务,多用户和真正的32位操作系统 2)支持多种硬件,多种硬件平台

3)对应用程序使用的内存进行保护 4)按需取盘 5)共享内存页面 6)使用分页技术的虚拟内存 7)优秀的磁盘缓冲调度功能 8)动态链接共享库 9)支持伪终端设备 10)支持多个虚拟控制台 11)支持多种CPU 12)支持数字协处理器387的软件模拟 13)支持多种文件系统 14)支持POSIX的任务控制 15)软件移植性好 16)与其它UNIX系统的兼容性 17)强大的网络功能 三、常用命令介绍 1、目录操作 和DOS相似,Linux采用树型目录管理结构,由根目录(/)开始一层层将 子目录建下去,各子目录以 / 隔开。用户login后,工作目录的位置称为 home directory,由系统管理员设定。‘~’符号代表自己的home directory,例 如 ~/myfile 是指自己home目录下myfile这个文件。 Linux的通配符有三种:’*’和’?’用法与DOS相同,‘-‘代表区间内 的任一字符,如test[0-5]即代表test0,test1,……,test5的集合。 (1)显示目录文件 ls 执行格式: ls [-atFlgR] [name] (name可为文件或目录名称) 例: ls 显示出当前目录下的文件 ls -a 显示出包含隐藏文件的所有文件 ls -t 按照文件最后修改时间显示文件 ls -F 显示出当前目录下的文件及其类型

linux进程间通讯的几种方式

1.信号:(signal)是一种处理异步事件的方式。信号时比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程外,还可以发送信号给进程本身。 2.信号量:(Semaphore)进程间通信处理同步互斥的机制。是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。 linux进程间通讯的几种方式的特点和优缺点,和适用场合 1. 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。 有名管道(named pipe) :有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。 信号量( semophore ) :信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。消息队列( message queue ) :消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。 信号( sinal ) :信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。 共享内存( shared memory):共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的IPC方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号量,配合使用,来实现进程间的同步和通信。

相关文档
相关文档 最新文档