进程间通讯
c语言进程间通信的几种方法

c语言进程间通信的几种方法一、管道(Pipe)管道是一种半双工的通信方式,它可以在两个相关的进程之间传递数据。
具体而言,管道可以分为匿名管道(只能在父子进程之间使用)和有名管道(可以在不相关的进程之间使用)。
1. 匿名管道匿名管道主要通过pipe函数创建,它只能在具有亲缘关系的进程之间使用。
父进程调用pipe函数创建管道后,可以通过fork函数创建子进程,并通过管道进行通信。
父进程通过write函数将数据写入管道,子进程通过read函数从管道中读取数据。
2. 有名管道有名管道是一种特殊的文件,可以在不相关的进程之间进行通信。
创建有名管道可以使用mkfifo函数,在进程间通信时,一个进程以写的方式打开管道,另一个进程以读的方式打开管道,就可以进行数据的读写。
二、共享内存(Shared Memory)共享内存是一种高效的进程间通信方式,它可以在多个进程之间共享同一块物理内存区域。
具体而言,共享内存的创建过程包括创建共享内存区域、映射到进程的虚拟地址空间和访问共享内存。
1. 创建共享内存区域使用shmget函数创建共享内存区域,需要指定共享内存的大小和权限等参数。
2. 映射到进程的虚拟地址空间使用shmat函数将共享内存区域映射到进程的虚拟地址空间,使得进程可以通过访问内存的方式进行通信。
3. 访问共享内存通过对共享内存区域的读写操作,实现进程间的数据交换。
三、消息队列(Message Queue)消息队列是一种可以在不相关的进程之间传递数据的通信方式。
它是一种存放在内核中的消息链表,进程可以通过系统调用对消息进行发送和接收。
1. 创建消息队列使用msgget函数创建消息队列,需要指定消息队列的键值和权限等参数。
2. 发送消息使用msgsnd函数向消息队列中发送消息,需要指定消息队列的标识符和消息的类型等参数。
3. 接收消息使用msgrcv函数从消息队列中接收消息,需要指定消息队列的标识符、接收消息的缓冲区和接收消息的类型等参数。
进程通信的几种方法

进程通信的几种方法进程通信是指在操作系统中,不同的进程之间进行数据交换和信息传递的过程。
在现代操作系统中,进程通信是非常重要的,因为多个进程之间的协作可以提高系统的性能和效率。
本文将介绍几种常见的进程通信方法。
1.管道通信管道通信是一种单向、半双工的通信方式,通过创建一个管道,将一个进程的输出连接到另一个进程的输入,从而实现数据的传输。
管道通信一般用于具有父子关系的进程之间或者具有共同祖先的进程之间。
2.消息队列通信消息队列通信是一种通过操作系统内核来传递消息的机制。
进程可以将消息发送到消息队列,其他进程则可以从消息队列中接收消息。
消息队列通信具有高效、可靠、灵活等特点,常用于进程之间传递数据量较大的情况。
3.共享内存通信共享内存通信是一种进程间共享内存区域的方式。
多个进程可以访问同一块内存区域,从而实现数据的共享。
共享内存通信的优点是速度快,因为进程之间不需要进行数据的复制,但是需要进程之间进行同步和互斥操作,以避免数据的冲突。
4.信号量通信信号量通信是一种通过操作系统提供的信号量机制来实现进程间同步和互斥的方式。
进程可以通过信号量来进行互斥操作,以确保共享资源的安全访问。
信号量通信常用于进程之间共享资源的管理和同步。
5.套接字通信套接字通信是一种通过网络进行进程通信的方式,常用于不同主机之间的进程通信。
套接字通信可以通过TCP或UDP协议来实现,具有跨平台、可靠性高等特点。
总结起来,进程通信是操作系统中非常重要的一部分,不同的进程之间可以通过各种方式进行数据的交换和信息的传递。
管道通信、消息队列通信、共享内存通信、信号量通信和套接字通信是常见的几种进程通信方法。
不同的通信方法适用于不同的场景,开发人员需要根据具体需求选择合适的通信方式。
进程通信的正确使用可以提高系统的性能和效率,确保系统的稳定运行。
进程间通信 IPC interprocess communication

进程间通信 IPC interprocess communication1,管道,FIFO2, 信号3,消息队列4,共享类存5.文件映射6.socket(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):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。
进程通讯管理实验报告(3篇)

第1篇一、实验目的1. 理解进程通信的概念和原理;2. 掌握进程通信的常用机制和方法;3. 能够使用进程通信机制实现进程间的数据交换和同步;4. 增强对操作系统进程管理模块的理解。
二、实验环境1. 操作系统:Linux2. 编程语言:C3. 开发环境:GCC三、实验内容1. 进程间通信的管道机制2. 进程间通信的信号量机制3. 进程间通信的共享内存机制4. 进程间通信的消息队列机制四、实验步骤1. 管道机制(1)创建管道:使用pipe()函数创建管道,将管道文件描述符存储在两个变量中,分别用于读和写。
(2)创建进程:使用fork()函数创建子进程,实现父子进程间的通信。
(3)管道读写:在父进程中,使用read()函数读取子进程写入的数据;在子进程中,使用write()函数将数据写入管道。
(4)关闭管道:在管道读写结束后,关闭对应的管道文件描述符。
2. 信号量机制(1)创建信号量:使用sem_open()函数创建信号量,并初始化为1。
(2)获取信号量:使用sem_wait()函数获取信号量,实现进程同步。
(3)释放信号量:使用sem_post()函数释放信号量,实现进程同步。
(4)关闭信号量:使用sem_close()函数关闭信号量。
3. 共享内存机制(1)创建共享内存:使用mmap()函数创建共享内存区域,并初始化数据。
(2)映射共享内存:在父进程和子进程中,使用mmap()函数映射共享内存区域。
(3)读写共享内存:在父进程和子进程中,通过指针访问共享内存区域,实现数据交换。
(4)解除映射:在管道读写结束后,使用munmap()函数解除映射。
4. 消息队列机制(1)创建消息队列:使用msgget()函数创建消息队列,并初始化消息队列属性。
(2)发送消息:使用msgsnd()函数向消息队列发送消息。
(3)接收消息:使用msgrcv()函数从消息队列接收消息。
(4)删除消息队列:使用msgctl()函数删除消息队列。
进程间通信和线程间通信的几种方式

进程间通信和线程间通信的⼏种⽅式进程进程(Process)是计算机中的程序关于某数据集合上的⼀次运⾏活动,是系统进⾏资源分配和调度的基本单位,是结构的基础。
在早期⾯向进程设计的计算机结构中,进程是程序的基本执⾏实体;在当代⾯向线程设计的计算机结构中,进程是线程的容器。
程序是指令、数据及其组织形式的描述,进程是程序的实体。
进程是⼀个具有独⽴功能的程序关于某个数据集合的⼀次运⾏活动。
它可以申请和拥有系统资源,是⼀个动态的概念,是⼀个活动的实体。
它不只是程序的,还包括当前的活动,通过的值和处理的内容来表⽰。
进程的概念主要有两点:第⼀,进程是⼀个实体。
每⼀个进程都有它⾃⼰的地址空间,⼀般情况下,包括区域(text region)、数据区域(data region)和(stack region)。
⽂本区域存储处理器执⾏的代码;数据区域存储变量和进程执⾏期间使⽤的动态分配的内存;堆栈区域存储着活动过程调⽤的指令和本地变量。
第⼆,进程是⼀个“执⾏中的程序”。
程序是⼀个没有⽣命的实体,只有器赋予程序⽣命时(操作系统执⾏之),它才能成为⼀个活动的实体,我们称其为。
进程是具有⼀定独⽴功能的程序关于某个数据集合上的⼀次运⾏活动,进程是系统进⾏资源分配和调度的⼀个独⽴单位。
每个进程都有⾃⼰的独⽴内存空间,不同进程通过进程间通信来通信。
由于进程⽐较重量,占据独⽴的内存,所以上下⽂进程间的切换开销(栈、寄存器、虚拟内存、⽂件句柄等)⽐较⼤,但相对⽐较稳定安全。
线程线程是进程的⼀个实体,是CPU调度和分派的基本单位,它是⽐进程更⼩的能独⽴运⾏的基本单位.线程⾃⼰基本上不拥有系统资源,只拥有⼀点在运⾏中必不可少的资源(如程序计数器,⼀组寄存器和栈),但是它可与同属⼀个进程的其他的线程共享进程所拥有的全部资源。
线程间通信主要通过共享内存,上下⽂切换很快,资源开销较少,但相⽐进程不够稳定容易丢失数据。
⼀个线程可以创建和撤消另⼀个线程,同⼀进程中的多个线程之间可以并发执⾏。
进程之间的四种通讯方式

1. 消息传递(管道,FIFO,posix和system v消息队列)
2. 同步(互斥锁,条件变量,读写锁,文件和记录锁,Posix和System V信号灯)
3. 共享内存区(匿名共享内存区,有名Posix共享内存区,有名System V共享内存区)
4. 在众多的消息传递技术—管道,FIFO,Posix消息队列和System V消息队列—中,可从一个信号处理程序中调用的函数只有read和write(适用于管道和FIFO).
比较不同形式的消息传递时,我 们感兴趣的有两种测量尺度:
1. 带宽(bandwidth):数据通过IPC通道转移的速度.为测量该值,我们从一个进程向另一个进程发送大量数据(几百万字节).我们还给不同大小的 I/O操作(例如管道和FIFO的write和read操作)测量该值,期待发现带宽随每个I/O操作的数据量的增长而增长的规律.
2. 延迟(latency):一个小的IPC消息从一个进程到令一个进程再返回来所花的时间.我们测量的是只有一个1个字节的消息从一个进程到令一个进程再回 来的时间(往返时间)
Hale Waihona Puke 在现实世界中,带宽告诉我们大块数据通过一个IPC通道发送出去需花多长时间,然而IPC也用于传递小的控制信 息,系统处理这些小消息所需的时间就由延迟提供.这两个数都很重要.
4. 过程调用(Solaris门,Sun RPC)
消息队列和过程调用往往单独使用,也就是说它们通常提供了自己的同步机制.相反,共享内存区通常需要由应用程序提供的某种同步形式才能 正常工作.解决某个特定问题应使用哪种IPC不存在简单的判定,应该逐渐熟悉各种IPC形式提供的机制,然后根据特定应用的要求比较它们的特性.
windows进程间通信的几种方法

windows进程间通信的几种方法(实用版4篇)目录(篇1)1.引言2.Windows进程间通信概述3.管道通信4.共享内存通信5.消息队列通信6.套接字通信7.结论正文(篇1)一、引言Windows操作系统以其强大的功能和灵活性,吸引了众多用户。
在Windows平台上,进程间通信(IPC)是实现应用程序之间数据交换和协作的关键。
本文将介绍几种常用的Windows进程间通信方法。
二、Windows进程间通信概述Windows进程间通信是指不同进程之间通过某种机制实现数据交换。
它允许应用程序在不同的线程或进程之间传递信息,从而实现协同工作。
在Windows平台上,有多种进程间通信机制可供选择,包括管道、共享内存、消息队列和套接字等。
三、管道通信1.概述:管道是一种用于不同进程之间数据交换的同步机制。
它提供了一种单向数据流,可实现父子进程之间的通信。
2.创建:使用CreateNamedPipe函数创建命名管道或使用CreatePipe函数创建匿名管道。
3.读取/写入:使用ReadFile和WriteFile函数进行数据的读取和写入。
4.关闭:使用CloseHandle函数关闭管道句柄。
四、共享内存通信1.概述:共享内存允许多个进程访问同一块内存区域,从而实现数据共享和快速数据访问。
2.创建:使用CreateFileMapping函数创建共享内存映射。
3.读取/写入:使用MapViewOfFile函数将共享内存映射到进程的地址空间,并进行数据的读取和写入。
4.同步:使用原子操作或信号量进行数据的同步和互斥访问。
五、消息队列通信1.概述:消息队列允许不同进程之间传递消息,实现异步通信。
它可以实现消息的批量发送和接收,适用于高并发的消息传递场景。
2.创建:使用CreateMailslot函数创建消息队列。
3.发送/接收:使用SendMessage函数发送消息,使用SendMessage 函数的异步版本接收消息。
Python进程间通信multiProcessingQueue队列实现详解

Python进程间通信multiProcessingQueue队列实现详解⼀、进程间通信IPC(Inter-Process Communication)IPC机制:实现进程之间通讯管道:pipe 基于共享的内存空间队列:pipe+锁的概念--->queue⼆、队列(Queue)2.1 概念-----multiProcess.Queue创建共享的进程队列,Queue是多进程安全的队列,可以使⽤Queue实现多进程之间的数据传递。
Queue([maxsize])创建共享的进程队列。
参数:maxsize是队列中允许的最⼤项数。
如果省略此参数,则⽆⼤⼩限制。
底层队列使⽤管道和锁定实现。
2.2 Queue⽅法使⽤2.2.1 q.get的使⽤:是从队列⾥⾯取值并且把队列⾯的取出来的值删掉,没有参数的情况下就是是默认⼀直等着取值就算是队列⾥⾯没有可取的值的时候,程序也不会结束,就会卡在哪⾥,⼀直等着from multiprocessing import Queueq = Queue() # ⽣成⼀个队列对象# put⽅法是往队列⾥⾯放值q.put('Cecilia陈')q.put('xuchen')q.put('喜陈')# get⽅法是从队列⾥⾯取值print(q.get())print(q.get())print(q.get())q.put(5)q.put(6)print(q.get())Cecilia陈xuchen喜陈52.2.2 Queue(参数) +参数的使⽤:Queue加参数以后,参数是数值参数实⼏就表⽰实例化的这个Queue队列可以放⼏个值当队列已经满的时候,再放值,程序会阻塞,但不会结束from multiprocessing import Queueq = Queue(3)q.put('Cecilia陈')q.put('xuchen')q.put('喜陈')print(q.full()) # 判断队列是否满了返回的是True/Falseq.put(2) # 当队列已经满的时候,再放值,程序会阻塞,但不会结束True 队列已经满了2.2.3 q.put(参数1,参数2,参数3,参数4):q.put(self, obj, block=True, timeout=None)self :put就相当于是Queue⾥的⼀个⽅法,这个时候q.put就相当于是队列对象q来调⽤对象的绑定⽅法,这个参数可以省略即可obj:是我们需要往队列⾥⾯放的值block=True :队列如果满了的话,再往队列⾥放值的话会等待,程序不会结束timeout=None:是再block这个参数的基础上的,当block的值为真的时候,timeout是⽤来等待多少秒,如果再这个时间⾥,队列⼀直是满的,那么程序就会报错并结束(Queue.Full异常)from multiprocessing import Queueq = Queue(3)q.put('zhao',block=True,timeout=2)q.put('zhao',block=True,timeout=2)q.put('zhao',block=True,timeout=2)q.put('zhao',block=True,timeout=5) # 此时程序将对等待5秒以后报错了2.2.4 q.get(参数1,参数2,参数3,参数4):q.get(self,block=True, timeout=None)self :get就相当于是Queue⾥的⼀个⽅法,这个时候q.get就相当于是队列对象q来调⽤对象的绑定⽅法,这个参数可以省略即可block=True :从队列q对象⾥⾯取值,如果娶不到值的话,程序不会结束timeout=None:是再block这个参数的基础上的,当block的值为真的时候,timeout是⽤来等待多少秒,如果再这个时间⾥,get 取不到队列⾥⾯的值的话,那么程序就会报错并结束(queue.Empty异常)from multiprocessing import Queueq = Queue()q.put('Cecilia陈')print(q.get())q.get(block=True,timeout=2) # 此时程序会等待2秒后,报错了,队列⾥⾯没有值了2.2.5 block=False:如果block的值是False的话,那么put⽅法再队列是满的情况下,不会等待阻塞,程序直接报错(Queue.Full异常)结束如果block的值是False的话,那么get⽅法再队列⾥⾯没有值的情况下,再去取的时候,不会等待阻塞,程序直接报错(queue.Empty异常)结束1.put()的block=Falsefrom multiprocessing import Queueq = Queue(2)q.put('Cecilia陈')q.put('喜陈')print(q.full())q.put('xichen',block=False) # 队列已经满了,我不等待了,直接报错2.get()的block=Flasefrom multiprocessing import Queueq = Queue(2)q.put('Cecilia陈')q.put('喜陈')print(q.get())print(q.get())print(q.get(block=False)) # 队列已经没有值了,我不等待了,直接报错2.2.6 put_nowait()/get_nowait()1.put_nowait() 相当于bolok=False,队列满的时候,再放值的时候,程序不等待,不阻塞,直接报错from multiprocessing import Queueq = Queue(2)q.put('Cecilia陈')q.put('喜陈')print(q.full())q.put_nowait('xichen') # 程序不等待,不阻塞,直接报错2.get_nowait() 相当于bolok=False,当队列⾥没有值的时候,再取值的时候,程序不等待,不阻塞,程序直接报错from multiprocessing import Queueq = Queue(2)q.put('Cecilia陈')q.put('喜陈')print(q.get())print(q.get())print(q.full())q.get_nowait()# 再取值的时候,程序不等待,不阻塞,程序直接报错三、代码实例3.1 单看队列的存取数据⽤法这个例⼦还没有加⼊进程通信,只是先来看看队列为我们提供的⽅法,以及这些⽅法的使⽤和现象。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
全国嵌入式人才培训基地
4. 进程间通信 上一页 第 30 章 进程 下一页
4. 进程间通信
请点评
每个进程各自有不同的用户地址空间, 任何一个进程的全局变量在另一个进程中 都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区, 进程 2 再从内核缓冲区把数据读走, 进程 1 把数据从用户空间拷到内核缓冲区, 内核提供的这种机制称为进程间通信(IPC,InterProcess Communication)。
如下图所示。
图 30.6. 进程间通信
4.1. 管道 请点评
管道是一种最基本的 IPC 机制,由 pipe 函数创建:
#include <unistd.h>
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. 管道
#include <stdlib.h> #include <unistd.h> #define MAXLINE 80
int main(void) { int n; int fd[2]; pid_t pid; char line[MAXLINE];
if (pipe(fd) < 0) { perror("pipe"); exit(1); } if ((pid = fork()) < 0) { perror("fork"); exit(1); } if (pid > 0) { /* parent */ close(fd[0]); write(fd[1], "hello world\n", 12); wait(NULL); } else { /* child */
close(fd[1]); n = read(fd[0], line, MAXLINE);
write(STDOUT_FILENO, line, n); } return 0; }
使用管道有一些限制:
•
•
两个进程通过一个管道只能实现单向通信,比如上面的例子,父进 程写子进程读,如果有时候也需要子进程写父进程读,就必须另开 一个管道。
请读者思考,如果只开一个管道,但是父进程不关闭读 端,子进程也不关闭写端,双方都有读端和写端,为什么不能实现 双向通信? 管道的读写端通过打开的文件描述符来传递, 因此要通信的两个进 程必须从它们的公共祖先那里继承管道文件描述符。
上面的例子是 父进程把文件描述符传给子进程之后父子进程之间通信, 也可以父 进程 fork 两次,把文件描述符传给两个子进程,然后两个子进程 之间通信,总之需要通过 fork 传递文件描述符使两个进程都能访 问同一管道,它们才能通信。
使用管道需要注意以下 4 种特殊情况(假设都是阻塞 I/O 操作,没有设置 O_NONBLOCK 标志): 1. 如果所有指向管道写端的文件描述符都关闭了 (管道写端的引用计 数等于 0),而仍然有进程从管道的读端读数据,那么管道中剩余 的数据都被读取后, 再次 read 会返回 0, 就像读到文件末尾一样。
2. 如果有指向管道写端的文件描述符没关闭 (管道写端的引用计数大 于 0),而持有管道写端的进程也没有向管道中写数据,这时有进 程从管道读端读数据,那么管道中剩余的数据都被读取后,再次 read 会阻塞,直到管道中有数据可读了才读取数据并返回。
3. 如果所有指向管道读端的文件描述符都关闭了 (管道读端的引用计 数等于 0),这时有进程向管道的写端 write,那么该进程会收到 信号 SIGPIPE,通常会导致进程异常终止。
在第 33 章 信号会讲到 怎样使 SIGPIPE 信号不终止进程。
4. 如果有指向管道读端的文件描述符没关闭 (管道读端的引用计数大 于 0),而持有管道读端的进程也没有从管道中读数据,这时有进 程向管道写端写数据,那么在管道被写满时再次 write 会阻塞,直 到管道中有空位置了才写入数据并返回。
管道的这四种特殊情况具有普遍意义。
在第 37 章 socket 编程要讲的 TCP socket 也具有管道的这些特性。
习题 请点评 1、在例 30.7 “管道”中,父进程只用到写端,因而把读端关闭,子进程只用 到读端,因而把写端关闭,然后互相通信,不使用的读端或写端必须关闭,请读 者想一想如果不关闭会有什么问题。
2、请读者修改例 30.7 “管道”的代码和实验条件,验证我上面所说的四种特 殊情况。
4.2. 其它 IPC 机制 请点评
进程间通信必须通过内核提供的通道, 而且必须有一种办法在进程中标识内核提 供的某个通道,上一节讲的管道是用打开的文件描述符来标识的。
如果要互相通 信的几个进程没有从公共祖先那里继承文件描述符, 它们怎么通信呢?内核提供 一条通道不成问题, 问题是如何标识这条通道才能使各进程都可以访问它?文件 系统中的路径名是全局的,各进程都可以访问,因此可以用文件系统中的路径名 来标识一个 IPC 通道。
FIFO 和 UNIX Domain Socket 这两种 IPC 机制都是利用文件系统中的特殊文件 来标识的。
可以用 mkfifo 命令创建一个 FIFO 文件:
$ mkfifo hello $ ls -l hello prw-r--r-- 1 akaedu akaedu 0 2008-10-30 10:44 hello
FIFO 文件在磁盘上没有数据块,仅用来标识内核中的一条通道,各进程可以打 开这个文件进行 read/write, 实际上是在读写内核通道 (根本原因在于这个 file 结构体所指向的 read、write 函数和常规文件不一样),这样就实现了进程间通 信。
UNIX Domain Socket 和 FIFO 的原理类似,也需要一个特殊的 socket 文件 来标识内核中的通道,例如/var/run 目录下有很多系统服务的 socket 文件:
$ ls -l /var/run/ total 52 srw-rw-rw- 1 root root 2008-10-30 00:24 acpid.socket ... srw-rw-rw- 1 root root 2008-10-30 00:25 gdm_socket ... srw-rw-rw- 1 root 2008-10-30 00:24 sdp ... srwxr-xr-x 1 root root 2008-10-30 00:42 synaptic.socket 0 root 0 0 0
文件类型 s 表示 socket, 这些文件在磁盘上也没有数据块。
UNIX Domain Socket 是目前最广泛使用的 IPC 机制,到后面讲 socket 编程时再详细介绍。
现在把进程之间传递信息的各种途径(包括各种 IPC 机制)总结如下:
• • • • • • • • •
父进程通过 fork 可以将打开文件的描述符传递给子进程 子进程结束时,父进程调用 wait 可以得到子进程的终止信息 几个进程可以在文件系统中读写某个共享文件, 也可以通过给文件 加锁来实现进程间同步 进程之间互发信号, 一般使用 SIGUSR1 和 SIGUSR2 实现用户自定义 功能 管道 FIFO mmap 函数,几个进程可以映射同一内存区 SYS V IPC,以前的 SYS V UNIX 系统实现的 IPC 机制,包括消 息队列、信号量和共享内存,现在已经基本废弃 UNIX Domain Socket,目前最广泛使用的 IPC 机制
上一页 3. 进程控制
上一级 起始页
全国嵌入式人才培训基地
下一页 5. 练习:实现简单的 Shell
。