当前位置:文档之家› 通信机制

通信机制

通信机制
通信机制

Linux 核心--6.进程间通讯机制

(2008-08-03 13:05:10)

签:

it

来源:原著: David A Rusling 翻译: Banyan & fifa (2001-04-27 13:56:30)第五章进程间通讯机制

进程在核心的协调下进行相互间的通讯。Linux支持大量进程间通讯(IPC)机制。除了信号和管道外,Linux 还支持Unix系统V中的IPC机制。

5.1 信号

信号是Unix系统中的最古老的进程间通讯方式。它们用来向一个或多个进程发送异步事件信号。信号可以从键盘中断中产生,另外进程对虚拟内存的非法存取等系统错误环境下也会有信号产生。信号还被shell程序用来向其子进程发送任务控制命令。

系统中有一组被详细定义的信号类型,这些信号可以由核心或者系统中其它具有适当权限的进程产生。使用kill命令(kill -l)可以列出系统中所有已经定义的信号。在我的系统(Intel系统)上运行结果如下:

1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL

5) SIGTRAP 6) SIGIOT 7) SIGBUS 8) SIGFPE

9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2

13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD

18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN

22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ

26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO

30) SIGPWR

当我在Alpha AXP中运行此命令时,得到了不同的信号个数。除了两个信号外,进程可以忽略这些信号中的绝大部分。其一是引起进程终止执行的SIGSTOP信号,另一个是引起进程退出的SIGKILL信号。至于其它信号,进程可以选择处理它们的具体方式。进程可以阻塞信号,如若不阻塞,则可以在自行处理此信号和将其转交核心处理之间作出选择。如果由核心来处理此信号,它将使用对应此信号的缺省处理方法。比如当进程接收到SIGFPE(浮点数异常)时,核心的缺省操作是引起core dump和进程的退出。信号没有固有的相对优先级。如果在同一时刻对于一个进程产生了两个信号,则它们将可能以任意顺序到达进程并进行处理。同时Linux并不提供处理多个相同类型信号的方式。即进程无法区分它是收到了1个还是42个SIGCONT信号。

Linux通过存储在进程task_struct中的信息来实现信号。信号个数受到处理器字长的限制。32位字长的处理器最多可以有32个信号而 64位处理器如Alpha AXP可以有最多64个信号。当前未处理的信号保存在signal域中,并带有保存在blocked中的被阻塞信号的屏蔽码。除了SIGSTOP和SIGKILL 外,所有的信号都能被阻塞。当产生可阻塞信号时,此信号可以保持一直处于待处理状态直到阻塞释放。Linux保存着每个进程处理每个可能信号的信息,它们保存在每个进程task_struct中的sigaction数组中。这些信息包括进程希望处理的信号所对应的过程地址,或者指示是忽略信号还是由核心来处理它的标记。通过系统调用,进程可以修改缺省的信号处理过程,这将改变某个信号的sigaction以及阻塞屏蔽码。

并不是系统中每个进程都可以向所有其它进程发送信号:只有核心和超级用户具有此权限。普通进程只能向具有相同uid和gid的进程或者在同一进程组中的进程发送信号。信号是通过设置task_struct结构中signal域里的某一位来产生的。如果进程没有阻塞信号并且处于可中断的等待状态,则可以

将其状态改成Running,同时如确认进程还处在运行队列中,就可以通过信号唤醒它。这样系统下次发生调度时,调度管理器将选择它运行。如果进程需要缺省的信号处理过程,则Linux可以优化对此信号的处理。例如SIGWINCH (X窗口的焦点改变)信号,其缺省处理过程是什么也不做。

信号并非一产生就立刻交给进程,而是必须等待到进程再次运行时才交给进程。每次进程从系统调用中退出前,它都会检查signal和blocked 域,看是否有可以立刻发送的非阻塞信号。这看起来非常不可靠,但是系统中每个进程都在不停地进行系统调用,如向终端输出字符。当然进程可以选择去等待信号,此时进程将一直处于可中断状态直到信号出现。对当前不可阻塞信号的处理代码放置在sigaction结构中。

如果信号的处理过程被设置成缺省则由核心来应付它。SIGSTOP信号的缺省处理过程是将当前进程的状态改变成为Stopped并运行调度管理器以选择一个新进程继续运行。SIGFPE的缺省处理过程则是引起core dump并使进程退出。当然,进程可以定义其自身的信号处理过程。一旦信号产生,这个过程就将被调用。它的地址存储在sigaction结构中。核心必须调用进程的信号处理例程,具体如何去做依赖于处理器类型,但是所有的CPU 必须处理这个问题:如果信号产生时,当前进程正在核心模式下运行并且马上要返回调用核心或者系统例程的进程,而该进程处在用户模式下。解决这个问题需要操纵进程的堆栈及寄存器。进程的程序计数器被设置成其信号处理过程的地址,而参数通过调用框架或者寄存器传递到处理例程中。当进程继续执行时,信号处理例程好象普通的函数调用一样。

Linux是POSIX兼容的,所以当某个特定信号处理例程被调用时,进程可以设定哪个信号可以阻塞。这意味着可以在进程信号处理过程中改变 blocked屏蔽码。当信号处理例程结束时,此blocked屏蔽码必须设置成原有值。因此,Linux添加了一个过程调用来进行整理工作,通过它来重新设置被发送信号进程调用栈中的原有blocked屏蔽码。对于同一时刻几个信号处理过程,

Linux通过堆栈方式来优化其使用,每当一个处理过程退出时,下一个处理过程必须等到整理例程结束后才执行。

5.2 管道

一般的Linux shell程序都允许重定向。如

$ ls | pr | lpr

在这个管道应用中,ls列当前目录的输出被作为标准输入送到pr程序中,而pr的输出又被作为标准输入送到lpr程序中。管道是单向的字节流,它将某个进程的标准输出连接到另外进程的标准输入。但是使用管道的进程都不会意识到重定向的存在,并且其执行结果也不会有什么不同。shell程序负责在进程间建立临时的管道。

图5.1 管道

在Linux中,管道是通过指向同一个临时VFS inode的两个file数据结构来实现的,此VFS inode指向内存中的一个物理页面。图5.1中每个file 数据结构指向不同的文件操作例程向量,一个是实现对管道的写,另一个从管道中读。

这样就隐藏了读写管道和读写普通的文件时系统调用的差别。当写入进程对

管道写时,字节被拷贝到共享数据页面中,当读取进程从管道中读时,字节从共享数据页面中拷贝出来。Linux必须同步对管道的访问。它必须保证读者和写者以确定的步骤执行,为此需要使用锁、等待队列和信号等同步机制。

当写者想对管道写入时,它使用标准的写库函数。表示打开文件和打开管道的描叙符用来对进程的file数据结构集合进行索引。Linux系统调用使用由管道file数据结构指向的write过程。这个write过程用保存在表示管道的VFS inode中的信息来管理写请求。

如果没有足够的空间容纳对所有写入管道的数据,只要管道没有被读者加锁。则Linux为写者加锁,并把从写入进程地址空间中写入的字节拷贝到共享数据页面中去。如果管道被读者加锁或者没有足够空间存储数据,当前进程将在管道inode的等待队列中睡眠,同时调度管理器开始执行以选择其它进程来执行。如果写入进程是可中断的,则当有足够的空间或者管道被解锁时,它将被读者唤醒。当数据被写入时,管道的VFS inode被解锁,同时任何在此 inode的等待队列上睡眠的读者进程都将被唤醒。

从管道中读出数据的过程和写入类似。

进程允许进行非阻塞读(这依赖于它们打开文件或者管道的方式),此时如果没有数据可读或者管道被加锁,则返回错误信息表明进程可以继续执行。阻塞方式则使读者进程在管道inode的等待队列上睡眠直到写者进程结束。当两个进程对管道的使用结束时,管道inode和共享数据页面将同时被遗弃。

Linux还支持命名管道(named pipe),也就是FIFO管道,因为它总是按照先进先出的原则工作。第一个被写入的数据将首先从管道中读出来。和其它管道不一样,FIFO管道不是临时对象,它们是文件系统中的实体并且可以通过mkfifo命令来创建。进程只要拥有适当的权限就可以自由使用FIFO管道。打开FIFO管道的方式稍有不同。其它管道需要先创建(它的两个file

数据结构,VFS inode和共享数据页面)而FIFO管道已经存在,只需要由使用者打开与关闭。在写者进程打开它之前,Linux必须让读者进程先打开此FIFO管道;任何读者进程从中读取之前必须有写者进程向其写入数据。FIFO 管道的使用方法与普通管道基本相同,同时它们使用相同数据结构和操作。

5.3 套接口

5.3.1 系统V IPC机制

Linux支持Unix系统V(1983)版本中的三种进程间通讯机制。它们是消息队列、信号灯以及共享内存。这些系统V IPC机制使用共同的授权方法。只有通过系统调用将标志符传递给核心之后,进程才能存取这些资源。这些系统V IPC对象使用与文件系统非常类似的访问控制方式。对象的引用标志符被用来作为资源表中的索引。这个索引值需要一些处理后才能得到。

系统中所有系统V IPC对象的Linux数据结构包含一个ipc_perm结构,它含有进程拥有者和创建者及组标志符。另外还有对此对象(拥有者,组及其它)的存取模式以及IPC对象键。此键值被用来定位系统V IPC对象的引用标志符。这样的键值一共有两组:公有与私有。如果此键为公有,则系统中任何接受权限检查的进程都可以找到系统V IPC对象的引用标志符。系统V IPC对象绝不能用一个键值来引用,而只能使用引用标志符。

5.3.2 消息队列

消息队列允许一个或者多个进程向它写入与读取消息。Linux维护着一个msgque消息队列链表,其中每个元素指向一个描叙消息队列的msqid_ds结构。当创建新的消息队列时,系统将从系统内存中分配一个msqid_ds结构,同时将其插入到数组中。

图5.2 系统V IPC消息队列

每个msqid_ds结构包含一个ipc_perm结构和指向已经进入此队列消息的指针。另外,Linux保留有关队列修改时间信息,如上次系统向队列中写入的时间等。msqid_ds包含两个等待队列:一个为队列写入进程使用而另一个由队列读取进程使用。

每次进程试图向写入队列写入消息时,系统将把其有效用户和组标志符与此队列的ipc_perm结构中的模式进行比较。如果允许写入操作,则把此消息从此进程的地址空间拷贝到msg数据结构中,并放置到此消息队列尾部。由于Linux严格限制可写入消息的个数和长度,队列中可能容纳不下这个消息。此时,此写入进程将被添加到这个消息队列的等待队列中,同时调用调度管理器选择新进程运行。当由消息从此队列中释放时,该进程将被唤醒。

从队列中读的过程与之类似。进程对这个写入队列的访问权限将被再次检验。读取进程将选择队列中第一个消息(不管是什么类型)或者第一个某特定类型的消息。如果没有消息可以满足此要求,读取进程将被添加到消息队列的读取等待队列中,然后系统运行调度管理器。当有新消息写入队列时,进程将被唤醒继续执行。

5.3.3 信号灯

信号灯最简单的形式是某个可以被多个进程检验和设置(test&set)的内存单元。这个检验与设置操作对每个进程而言是不可中断或者说是一个原子性操作;一旦启动谁也终止不了。检验与设置操作的结果是信号灯当前值加1,这个值可以是正数也可以是负数。根据这个操作的结果,进程可能可以一直睡

眠到此信号灯的值被另一个进程更改为止。信号灯可用来实现临界区(critical region):某一时刻在此区域内的代码只能被一个进程执行。

如果你有多个协作进程从一个数据文件中读取与写入记录。有时你可能需要这些文件访问遵循严格的访问次序。那么可在文件操作代码上使用一个初始值为1的信号灯,它带有两个信号灯操作,一个检验并对信号灯值减1,而另一个检验并加1。第一个访问文件的进程将试图将信号灯值减1,如果获得成功则信号灯值变成了0。此进程于是开始使用这个数据文件,但是此时如果另一进程也想将信号灯值减1,则信号灯值将为-1,这次操作将会失败。它将挂起执行直到第一个进程完成对此数据文件的使用。此时这个等待进程将被唤醒,这次它对信号灯的操作将成功。

图5.3 系统V IPC信号灯

每个系统V IPC信号灯对象对应一个信号灯数组,Linux使用semid_ds结构来表示。系统中所有semid_ds结构由一组 semary指针来指示。在每个信号灯数组中有一个sem_nsems,它表示一个由sem_base指向的sem结构。授权的进程可以使用系统调用来操纵这些包含系统V IPC信号灯对象的信号灯数组。这个系统调用可以定义许多种操作,每个操作用三个输入来描叙:信号灯索引、操作值和一组标志。信号灯索引是一个信号灯数组的索引,而操作值是将被加到信号灯上的数值。首先Linux将检查是否所有操作已经成功。如果操作值与信号灯当前数值相加大于0,或者操作值与信号灯当前值都是0,操作将会成功。如果所有信号灯操作失败,Linux仅仅会把那些操作标志没有要求系统调用为非阻塞类型的进程挂起。进程挂起后,Linux必须保存信号灯操作的执行状态并将当前进程放入等待队列。系统还在堆栈上建立sem_queue

结构并填充各个域。这个sem_queue 结构将被放到此信号灯对象等待队列的尾部(使用sem_pending和sem_pending_last指针)。系统把当前进程置入 sem_queue结构中的等待队列(sleeper)中,然后启动调度管理器选择其它进程运行。

如果所有这些信号灯操作都成功则无需挂起当前进程,Linux将对信号灯数组中的其他成员进行相同操作,然后检查那些处于等待或者挂起状态的进程。首先,Linux将依次检查挂起队列(sem_pending) 中的每个成员,看信号灯操作能否继续。如果可以则将其sem_queue结构从挂起链表中删除并对信号灯数组发出信号灯操作。Linux还将唤醒处于睡眠状态的进程并使之成为下一个运行的进程。如果在对挂起队列的遍历过程中有的信号灯操作不能完成则Linux将一直重复此过程,直到所有信号灯操作完成且没有进程需要继续睡眠。

但是信号灯的使用可能产生一个严重的问题:死锁。当一个进程进入临界区时它改变了信号灯的值而离开临界区时由于运行失败或者被kill而没有改回信号灯时,死锁将会发生。Linux通过维护一组描叙信号灯数组变化的链表来防止该现象的发生。它的具体做法是让Linux将把此信号灯设置为进程对其进行操作前的状态。这些状态值被保存在使用该信号灯数组进程的semid_ds 和task_struct结构的sem_undo结构中。

信号灯操作将迫使系统对它引起的状态变化进行维护。Linux为每个进程维护至少一个对应于信号灯数组的sem_undo结构。如果请求进行信号灯操作的进程没有该结构,则必要时Linux会为其创建一个。这个sem_undo 结构将同时放入此进程的task_struct结构和此信号灯数组的 semid_ds结构中。当对信号灯进行操作时,信号灯变化值的负数被置入进程的sem_undo结构中该信号的入口中。所以当操作值为2时,则此信号灯的调整入口中将加入一个-2。

象正常退出一样,当进程被删除时,Linux将遍历该进程的sem_undo集合对

信号灯数组使用调整值。如果信号灯集合被删除而 sem_undo数据结构还在进程的task_struct结构中则此信号灯数组标志符将被置为无效。此时信号灯清除代码只需丢弃sem_undo结构即可。

5.3.4 共享内存

共享内存允许一个或多个进程通过同时出现在它们虚拟地址空间中的内存来通讯。此虚拟内存的页面出现在每个共享进程页表中。但此页面并不一定位于所有共享进程虚拟内存的相同位置。和其它系统V IPC对象的使用方法一样,对共享内存区域的访问是通过键和访问权限检验来控制的。一旦内存被共享,则再不会检验进程对对象的使用方式。它依赖于其它机制,如系统V 信号灯,来同步对共享内存的访问。

图5.4 系统V IPC共享内存

每个新创建的共享内存区域由一个shmid_ds数据结构来表示。它们被保存再shm_segs数组中。shmid_ds数据结构描叙共享内存的大小,进程如何使用以及共享内存映射到其各自地址空间的方式。由共享内存创建者控制对此内存的存取权限以及其键是公有还是私有。如果它由足够权限,它还可以将此共享内存加载到物理内存中。

每个使用此共享内存的进程必须通过系统调用将其连接到虚拟内存上。这时进程创建新的vm_area_struct来描叙此共享内存。进程可以决定此共享内存在其虚拟地址空间的位置,或者让Linux选择一块足够大的区域。新的

vm_area_struct结构将被放到由shmid_ds指向的 vm_area_struct链表中。通过vm_next_shared和vm_prev_shared 指针将它们连接起来。虚拟内存在连接时并没有创建;进程访问它时才创建。

当进程首次访问共享虚拟内存中的页面时将产生页面错。当取回此页面后,Linux找到了描叙此页面的vm_area_struct数据结构。它包含指向使用此种类型虚拟内存的处理函数地址指针。共享内存页面错误处理代码将在此shmid_ds对应的页表入口链表中寻找是否存在此共享虚拟内存页面。如果不存在,则它将分配物理页面并为其创建页表入口。同时还将它放入当前进程的页表中,此入口被保存在shmid_ds结构中。这意味着下个试图访问此内存的进程还会产生页面错误,共享内存错误处理函数将为此进程使用其新创建的物理页面。这样,第一个访问虚拟内存页面的进程创建这块内存,随后的进程把此页面加入到各自的虚拟地址空间中。

当进程不再共享此虚拟内存时,进程和共享内存的连接将被断开。如果其它进程还在使用这个内存,则此操作只影响当前进程。其对应的

vm_area_struct结构将从shmid_ds结构中删除并回收。当前进程对应此共享内存地址的页表入口也将被更新并置为无效。当最后一个进程断开与共享内存的连接时,当前位于物理内存中的共享内存页面将被释放,同时还有此共享内存的shmid_ds结构。

当共享内存没有被锁入物理内存时,情况将更加复杂。此时共享内存页面可能会在内存使用高峰期,被交换到系统的交换磁盘上。共享内存如何被交换与调入物理内存将在mm一章中详细描叙。

进程间通信(1)

无名管道的用法 无名管道又被称为pipe,是进程间通信的一种方式。pipe具有以下特点: ●只能用于具有血缘关系的进程之间 ●半双工的通信模式,具有固定的读端和写端 ●一种特殊的文件,存在于内存中。可通过read、write对其操作 因为pipe存在于内存中,所以无法像操作普通文件那样通过指定路径来打开文件。通常的做法是在父进程中创建管道,再创建子进程。由于子进程继承了父进程打开的文件描述符,所以父子进程就可以通过创建的管道进行通信。 为了在父进程中创建管道,需要先定义一个包含两个元素的整型数组,用来存放管道读端和写端对应的文件描述符。该数组在创建管道时作为参数传递。要注意的是,管道是一种半双工方式,即对于进程来说,要么只能读管道,要么只能写管道。不允许对管道又读又写。 其中数组的第一个元素固定代表管道的读端,第二个元素代表管道的写端。对于一个进程来说,只会用到其中一个。 若读取管道时没有数据,则进程会被阻塞,直到有数据可读。写管道时除非管道已满,一般情况下写入操作很快会返回。 这里假设父进程读管道,子进程写管道。参考代码如下所示: int pfd[2]; pid_t pid; if ( pipe(pfd) < 0 ) // 创建管道失败 { perror(“fail to create pipe : ”); exit(-1); } if ( (pid=fork()) == -1 ) // 创建子进程失败 { perror(“fail to create child process : ”); exit(-1); } else if ( pid == 0 ) // 子进程

进程间通信方式比较

进程间的通信方式: 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.doczj.com/doc/808649693.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) 消息队列和过程调用往往单独使用,也就是说它们通常提供了自己的同步机制.相反,共享内存区

基于java的进程通信

1 仲恺农业工程学院实验报告纸 计算机科学与工程 (院、系) 网络工程 专业 083 班 组 《操作系统》 实验二 进程通信 一.实验目的: 1、 理解进程消息通信的概念,如何实现两个创建进程之间的数据传递。。 2、 理解进程共享变量的进程通信。 二.实验内容: 1、 选择Window 或Linux ,并选择该操作系统中一种进程通信的方式。 2、 查找该进程通信的API 使用方式,设计出一个合适的应用程序。 3、 采用高级程序语言实现该应用程序。 4、 测试进程通信程序,能够满足微机操作系统中进程之间的通信。 三.实验步骤和过程 1、 进程通信的知识点: (1)、进程通信的概念:进程之间互相交换信息的工作称为进程通信IPC (2)、进程通信的方式:信号(signal )通信机制; 共享存储区 (sharedmemory)通信机制;共享文件(shared file)通信机制;消息传递(message passing)通信机制。 (3)、进程通信机制:管道通信机制,共享主存通信机制,消息传递通信机制。 2、程序设计环境 (1)、Widows7操作系统,eclipse 平台! (2)、套接字(socket )通信 套接字通信,其中一个运行在客户端,称之为ClientSocket ,另一个运行于服务器端面,称为ServerSocket 。根据连接启动的方式以及本地要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听、

2 客户端请求、连接确认。 服务器监听是指服务端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。 客户端请求是由客户端的套接字提出连接请求,要连接的目标是服务器端套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器套接字的地址和端口号,然后再向服务器端套接字提出连接请求。 连接确认是当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的信息发送给客户端,一旦客户端确认了此连接,连接即可建立。而服务器端继续处于监听状态,继续接收其他客户端的连接请求。 使用套接字进行数据处理有两种基本模式:同步和异步。 同步模式: 同步模式的特点是在通过Socket 进行连接、接收、发送数据时,客户机和服务器在接收到对方响应前会出于阻塞状态,即一直等到收到对方请求进才继续执行下面的语句。可见,同步模式只适用于数据处理不太多的场合。当程序执行的任务很多时,长时间的等待可能会让用户无法忍受。 异步模式: 异步模式的特点是在通过Socket 进行连接、接收、发送操作时,客户机或服务器不会处于阻塞方式,而是利用callback 机制进行连接、接收、发送处理,这样就可以在调用发送或接收的方法后直接返回,并继续执行下面的程序。可见,异步套接字特别适用于进行大量数据处理的场合。 使用同步套接字进行编程比较简单,而异步套接字编程则比较复杂。

进程间通信实验报告

进程间通信实验报告 班级:10网工三班学生姓名:谢昊天学号:1215134046 实验目的和要求: Linux系统的进程通信机构 (IPC) 允许在任意进程间大批量地交换数据。本实验的目的是了解和熟悉Linux支持的消息通讯机制及信息量机制。 实验内容与分析设计: (1)消息的创建,发送和接收。 ①使用系统调用msgget (), msgsnd (), msgrev (), 及msgctl () 编制一长度为1k 的消息的发送和接收程序。 ②观察上面的程序,说明控制消息队列系统调用msgctl () 在此起什么作用? (2)共享存储区的创建、附接和段接。 使用系统调用shmget(),shmat(),sgmdt(),shmctl(),编制一个与上述功能相同的程序。(3)比较上述(1),(2)两种消息通信机制中数据传输的时间。 实验步骤与调试过程: 1.消息的创建,发送和接收: (1)先后通过fork( )两个子进程,SERVER和CLIENT进行通信。 (2)在SERVER端建立一个Key为75的消息队列,等待其他进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出SERVER 。SERVER每接收到一个消息后显示一句“(server)received”。 (3)CLIENT端使用Key为75的消息队列,先后发送类型从10到1的消息,然后退出。最后的一个消息,既是 SERVER端需要的结束信号。CLIENT每发送一条消息后显示一句“(client)sent”。 (4)父进程在 SERVER和 CLIENT均退出后结束。 2.共享存储区的创建,附接和断接: (1)先后通过fork( )两个子进程,SERVER和CLIENT进行通信。 (2)SERVER端建立一个KEY为75的共享区,并将第一个字节置为-1。作为数据空的标志.等待其他进程发来的消息.当该字节的值发生变化时,表示收到了该消息,进行处理.然后再次把它的值设为-1.如果遇到的值为0,则视为结束信号,取消该队列,并退出SERVER.SERVER 每接收到一次数据后显示”(server)received”. (3)CLIENT端建立一个为75的共享区,当共享取得第一个字节为-1时, Server端空闲,可发送请求. CLIENT 随即填入9到0.期间等待Server端再次空闲.进行完这些操作后, CLIENT退出. CLIENT每发送一次数据后显示”(client)sent”. (4)父进程在SERVER和CLIENT均退出后结束。 实验结果: 1.消息的创建,发送和接收: 由 Client 发送两条消息,然后Server接收一条消息。此后Client Server交替发送和接收消息。最后一次接收两条消息。Client 和Server 分别发送和接收了10条消息。message 的传送和控制并不保证完全同步,当一个程序不再激活状态的时候,它完全可能继续睡眠,造成上面现象。在多次send message 后才 receive message.这一点有助于理解消息转送的实现机理。

进程间的通信

实验三进程间的通信 【实验类型】 综合性实验 【目的要求】 学习如何利用管道机制、消息缓冲队列、共享存储区机制进行进程间的通讯,并加深对上述通信机制的理解。 【内容提要】 1、了解系统调用pipe()、msgget()、msgsnd()、msgrcv ()、msgctl()、shmget()、shmat()、shmdt()、shmctl()的功能和实现过程。 2、编写一段程序,使其用管道来实现父子进程之间的进程通讯。子进程向父进程发送自己的进程标识符,以及字符串“is sending a message to parent!”。父进程则通过管道读出子进程发来的消息,将消息显示在屏幕上,然后终止。 3、编写一段程序,使用系统调用fork()来创建两个子进程CLIENT进程和SERVER进程,使其用消息缓冲队列来实现CLIENT进程和SERVER进程之间的通信。SERVER端建立一个Key为75的消息队列,等待其他进程发来的消息。当遇到类型为1的消息,则作为结束信号,取消该队列,并退出SERVER。SERVER每接收到一条消息后显示一句“(server) received”。CLIENT端使用Key为75的消息队列,先后发送类型从10到1的消息,然后退出。最后的一个消息,即是SERVER端需要的结束信号。CLIENT每发送一条消息后显示一句“(client) sent”。父进程在SERVER和CLIENT均退出后结束。 4、编写一个与3具有类似功能的程序,使其用共享存储区来实现两个进程之间的通讯。 【主要仪器设备】 每人一台计算机,硬件要求:CPU PII以上,64M内存,1OOM硬盘空间即可;软件要求: Linux操作系统。

进程间的通信

# 管道( 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),就表示了对应的文件映射对象是从操作系统页面文件访问内存,其它进程打开该文件映射

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,就像读到文件末尾一样。

进程的消息通信_带答案版

实验二进程管理 2.2 进程的消息通信 1.实验目的 (1) 加深对进程通信的理解,理解进程消息传递机制。 (2) 掌握进程通信相关系统调用。 (3) 理解系统调用和用户命令的区别。 2.实验类型:验证型 3.实验学时:2 4.实验原理和知识点 (1) 实验原理:消息通信机制允许进程之间大批量交换数据。消息通信机制是以消息队列为基础的,消息队列是消息的链表。发送进程将消息挂入接收进程的消息队列,接收进程从消息队列中接收消息。消息队列有一个消息描述符。对消息队列的操作是通过描述符进行的。任何进程,只要有访问权并且知道描述符,就可以访问消息队列。每个消息包括一个正长整型的类型字段,和一个非负长度的数据。进程读或写消息时,要给出消息的类型。若队列中使用的消息类型为0,则读取队列中的第一个消息。 (2) 知识点:消息、消息队列 5.实验环境(硬件环境、软件环境): (1)硬件环境:Intel Pentium III 以上CPU,128MB以上内存,2GB以上硬盘 (2)软件环境:linux操作系统。 6. 预备知识

(1) msgget()系统调用: 头文件#include 函数原型int msgget(key_t key, int flag); 功能:创建消息队列,或返回与key对应的队列描述符。成功返回消息描述符,失败则返回-1。 参数:key是通信双方约定的队列关键字,为长整型数。flag是访问控制命令,它的低9位为访问权限(代表用户、组用户、其他用户的读、写、执行访问权),其它位为队列建立方式。(例:rwxrwx---:111111000) (2) msgsnd()系统调用: 头文件#include 函数原型int msgsnd(int id, struct msgbuf *msgp,int size,int flag); 功能:发送一个消息。成功返回0,失败返回-1。 参数:id是队列描述符。msgp是用户定义的缓冲区。size是消息长度。flag是操作行为,若(flag&IPC_NOWAIT)为真,调用进程立即返回;若(flag&IPC_NOWAIT)为假,调用进程阻塞,直到消息被发送出去或队列描述符被删除或收到中断信号为止。缓冲区结构定义如下:struct msgbuf{ long mtype; char mtext[n]; }; (3) msgrcv()系统调用: 头文件#include 函数原型int msgrcv(int id, struct msgbuf *msgp, int size,int type,int flag); 功能:接收一个消息。成功返回消息正文长度,失败返回-1。

进程间通讯机制

进程间通讯机制 进程在核心的协调下进行相互间的通讯。Linux支持大量进程间通讯(IPC) 机制。除了信号和管道外,Linux 还支持Unix系统V中的IPC机制。 信号 信号是Unix系统中的最古老的进程间通讯方式。它们用来向一个或多个进程发送异步事件信号。信号可以从键盘中断中产生,另外进程对虚拟内存的非法存取等系统错误环境下也会有信号产生。信号还被shell程序用来向其子进程发送任务控制命令。 系统中有一组被详细定义的信号类型,这些信号可以由核心或者系统中其它具有适当权限的进程产生。使用kill命令(kill -l)可以列出系统中所有已经定义的信号。在我的系统(Intel系统)上运行结果如下: 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGIOT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 当我在Alpha AXP中运行此命令时,得到了不同的信号个数。除了两个信号外,进程可以忽略这些信号中的绝大部分。其一是引起进程终止执行的SIGSTOP信号,另一个是引起进程退出的SIGKILL信号。至于其它信号,进程可以选择处理它们的具体方式。进程可以阻塞信号,如若不阻塞,则可以在自行处理此信号和将其转交核心处理之间作出选择。如果由核心来处理此信号,它将使用对应此信号的缺省处理方法。比如当进程接收到SIGFPE(浮点数异常)时,核心的缺省操作是引起core dump和进程的退出。信号没有固有的相对优先级。如果在同一时刻对于一个进程产生了两个信号,则它们将可能以任意顺序到达进程并进行处理。

进程间通信的几种方式

进程间通信的几种方式 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的变种都支持套接字

浅析分布式系统进程间通信

浅析分布式系统进程间通信 摘要:若干大量独立的计算机通过网络联系在一起,组成了分布式系统,在这种环境下,合作进程通过消息的传递进行通信需要访问分布在整个网络中的资源,所以一个好的通信机制比较重要。 关键词:分布式系统;进程间通信;通信机制 随着微型电子技术的发展,计算机的硬件成本不断下降,计算机应用技术得到了广泛的应用和很大的提高。特别是高性能微处理器的开发和高速计算机网络技术的发明,可以把若干由大量计算机组成的计算机系统彼此通过高速网络连接,这种系统一般称为分布式系统。分布式系统是若干独立计算机和用于交换信息的通信设备的集合,这些计算机对于用户来说就像是单个相关系统。它主要提供分布计算机和分布处理功能。随着Internet技术的分速发展和应用,进程间通信已经成为分布式系统的重要核心。 一、分布式系统简介 分布式系统便于资源共享。各种信息、文件、数据库和各种昂贵的硬件资源被分布式地管理和维护,并为用户的访问提供了方便。这样就能节省大量的重复投资。 分布式操作系统是运行在分布式计算机系统的操作系统。它是在多机环境下,负责控制和管理以协同方式工作的多种系统资源,进程的同步和执行,处理机间通信,调度等控制事务,自动实行全系统范围为的任务分配和负载平衡,方便用户使用,并具有高度并行性的一种高级系统软件。 二、分布式系统间的通信 一个分布式操作系统应该包括网络上的所有计算机,在一个分布式环境下,合作进行通过消息的传递进行通信因为需要访问分布在整个网络中的拥有资源,所以一个好的通信机制相当重要,进程间通信是一切分布式系统的核心。本文主要介绍以下四种通信模型,远程过程调用(remote procedure call,RPC)、远程方法调用(remote method invocation,RMI)、面向消息的中间件(message-oriented

进程通信实验报告

操作系统实验报告(三) 进程通信 专业:软件工程 姓名:XXX 班级:XXX 学号:XXX 指导老师:XXX 2013/12/3

实验三:进程通信 一.实验目的 加深对进程通信的理解。 熟悉消息通信机制、共享存储器通信机制,进一步认识其与信号量通信的区别。二.实验内容 1)编程实现基于消息缓冲队列机制的进程通信数据结构和通信原语(创建消息、发送消息、接收消息); 2)最后编写主函数对所做工作进行测试 三.实验步骤 (1)任务分析:实现进程通信,需要建立创建消息函数、发送消息函数、接收消息函数,需要用到进程中的Send和Receive原语 (2)程序设计: a.总体设计:创建两个windows窗体应用程序,分别用于发送消息和接收消息,可以采用C#实现。 b.具体实现 ①创建应用程序Sendmessage,在windows窗体上放置一个文本框输入要发送 的消息,一个按钮控件,单击按钮控件发送消息,编辑ButtonOnclick()事件,来编辑发送消息函数,发送后弹出消息发送成功对话框。 ②创建应用程序Receivemessage,在windows窗口上放置一个文本框用于 接收消息,放置一个Button按钮,并编辑ButtonOnclick()事件,来编辑接收消 息函数,成功后弹出成功接收对话框。 ③程序中的发送接收需要用到系统中的函数,将在实验代码中给与提示。 (4)调试与测试 实验结果: 发送消息: 接收消息:

四.实验总结 进程通信实验主要是通过通信原语机制创建消息发送函数和消息接收函数来模拟实现进程间的通信,在实验过程中,一些通信机制不是太明确,通过在网上查找资料以及和同学们交流,最终完成了进程通信实验,通过这次实验,我对进程间的通信原理多了更深一步的了解,为学习操作系统知识建立了良好的实践基础。 五.附录 ①发送消息函数源码: using System; using System.Collections.Generic; using https://www.doczj.com/doc/808649693.html,ponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Runtime.InteropServices; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); }

进程间通讯

全国嵌入式人才培训基地
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. 管道

进程间通信方式总结

程序员必须让拥有依赖关系的进程集协调,这样才能达到进程的共同目标。可以使用两种技术来达到协调。第一种技术在具有通信依赖关系的两个进程间传递信息。这种技术称做进程间通信(interprocess communication)。第二种技术是同步,当进程间相互具有合作依赖时使用。这两种类型的依赖关系可以同时存在。 一般而言,进程有单独的地址空间。我们可以了解下可执行程序被装载到内存后建立的一系列映射等理解这一点。如此以来意味着如果我们有两个进程(进程A 和进程B),那么,在进程A中声明的数据对于进程B是不可用的。而且,进程B看不到进程A中发生的事件,反之亦然。如果进程A和B一起工作来完成某个任务,必须有一个在两个进程间通信信息和时间的方法。我们这里可以去看看基本的进程组件。注意进程有一个文本、数据以及堆栈片断。进程可能也有从自由存储空间中分配的其它内存。进程所占有的数据一般位于数据片断、堆栈片断或进程的动态分配内存中。数据对于其它进程来说是受保护的。为了让一个进程访问另外一个进程的数据,必须最终使用操作系统调用。与之类似,为了让一个进程知道另一个进程中文本片断中发生的事件,必须在进程间建立一种通信方式。这也需要来自操作系统API的帮助。当进程将数据发送到另一进程时,称做IPC(interprocess communication,进程间通信)。 下面先列举几种不同类型的进程间通信方式: 一、环境变量、文件描述符: 当创建一个子进程时,它接受了父进程许多资源的拷贝。子进程接受了父进程的文本、堆栈 以及数据片断的拷贝。子进程也接受了父进程的环境数据以及所有文件描述符的拷贝。子进

linux进程间通讯的几种方式

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

通信机制

Linux 核心--6.进程间通讯机制 (2008-08-03 13:05:10) 标 签: it 来源:原著: David A Rusling 翻译: Banyan & fifa (2001-04-27 13:56:30)第五章进程间通讯机制 进程在核心的协调下进行相互间的通讯。Linux支持大量进程间通讯(IPC)机制。除了信号和管道外,Linux 还支持Unix系统V中的IPC机制。 5.1 信号 信号是Unix系统中的最古老的进程间通讯方式。它们用来向一个或多个进程发送异步事件信号。信号可以从键盘中断中产生,另外进程对虚拟内存的非法存取等系统错误环境下也会有信号产生。信号还被shell程序用来向其子进程发送任务控制命令。 系统中有一组被详细定义的信号类型,这些信号可以由核心或者系统中其它具有适当权限的进程产生。使用kill命令(kill -l)可以列出系统中所有已经定义的信号。在我的系统(Intel系统)上运行结果如下: 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGIOT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ

26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 当我在Alpha AXP中运行此命令时,得到了不同的信号个数。除了两个信号外,进程可以忽略这些信号中的绝大部分。其一是引起进程终止执行的SIGSTOP信号,另一个是引起进程退出的SIGKILL信号。至于其它信号,进程可以选择处理它们的具体方式。进程可以阻塞信号,如若不阻塞,则可以在自行处理此信号和将其转交核心处理之间作出选择。如果由核心来处理此信号,它将使用对应此信号的缺省处理方法。比如当进程接收到SIGFPE(浮点数异常)时,核心的缺省操作是引起core dump和进程的退出。信号没有固有的相对优先级。如果在同一时刻对于一个进程产生了两个信号,则它们将可能以任意顺序到达进程并进行处理。同时Linux并不提供处理多个相同类型信号的方式。即进程无法区分它是收到了1个还是42个SIGCONT信号。 Linux通过存储在进程task_struct中的信息来实现信号。信号个数受到处理器字长的限制。32位字长的处理器最多可以有32个信号而 64位处理器如Alpha AXP可以有最多64个信号。当前未处理的信号保存在signal域中,并带有保存在blocked中的被阻塞信号的屏蔽码。除了SIGSTOP和SIGKILL 外,所有的信号都能被阻塞。当产生可阻塞信号时,此信号可以保持一直处于待处理状态直到阻塞释放。Linux保存着每个进程处理每个可能信号的信息,它们保存在每个进程task_struct中的sigaction数组中。这些信息包括进程希望处理的信号所对应的过程地址,或者指示是忽略信号还是由核心来处理它的标记。通过系统调用,进程可以修改缺省的信号处理过程,这将改变某个信号的sigaction以及阻塞屏蔽码。 并不是系统中每个进程都可以向所有其它进程发送信号:只有核心和超级用户具有此权限。普通进程只能向具有相同uid和gid的进程或者在同一进程组中的进程发送信号。信号是通过设置task_struct结构中signal域里的某一位来产生的。如果进程没有阻塞信号并且处于可中断的等待状态,则可以

Windows XP 系统进程通信机制

Windows XP 系统进程通信机制 摘要:该文主要论述了Windows XP 系统进程通信机制。文章描述了进程通信的概念,分 别论述了低级通信机制和高级通信机制,并进一步对其中的重要成分进行了详细的描述,另外还介绍了Windows XP的其他通信机制。 1. 进程通信的概念 进程是程序的一次执行,是一个程序及其数据在处理机上顺序执行时所发生的活动,是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。 进程实体,由程序段、相关数据段及PCB组成。 在引入了进程实体的概念后,我们可以把传统OS中的进程定义为:“进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位”。 进程通信是指进程之间的信息交换。根据所交换的信息量的多少分为: 低级通信进程之间交换的信息量较少且效率低。如进程同步和互斥。 效率低 对用户不透明 高级通信 共享存储器系统指进程之间通过对共享存储区读写来交换数据。 消息传递系统指进程间的通信以消息为单位,程序员可通过通信 原语实现通信。 管道通信系统发送进程(写进程)以字符流形式将大量数据送入 管道(管道:用于连接读进程和写进程以实现它们之间通信的共享 文件),接收进程(读进程)从管道接收数据。 2.Windows XP的进程互斥和同步(低级通信) 三种同步对象:互斥对象(Mutex)、信号量对象(Semaphore)、事件对象(Event)。它们都有一个用户指定的对象名称,不同进程中用同样的对象名称来创建或打开对象,从而获得该对象在本进程的句柄。 互斥对象:即互斥信号量,在一个时刻只能被一个线程使用。 ——相关API:CreateMutex(创建一个互斥对象,返回对象句柄)、OpenMutex(打开并返回一个已存在的互斥对象句柄)、ReleaseMutex(释放对互斥对象的占用)。 信号量对象:即资源信号量,用于限制并发访问的线程数。

相关主题
文本预览
相关文档 最新文档