本节书摘来自异步社区《UNIX网络编程 卷2:进程间通信(第2版)》一书中的第1章,第1.2节,作者:【美】W. Richard Stevens著,更多章节内容可以访问云栖社区“异步社区”公众号查看
1.2 进程、线程与信息共享
按照传统的Unix编程模型,我们在一个系统上运行多个进程,每个进程都有各自的地址空间。Unix进程间的信息共享可以有多种方式。图1-1对此作了总结。
(1)左边的两个进程共享存留于文件系统中某个文件上的某些信息。为访问这些信息,每个进程都得穿越内核(例如read、write、lseek等)。当一个文件有待更新时,某种形式的同步是必要的,这样既可保护多个写入者,防止相互串扰,也可保护一个或多个读出者,防止写入者的干扰。
(2)中间的两个进程共享驻留于内核中的某些信息。管道是这种共享类型的一个例子,System V消息队列和System V信号量也是。现在访问共享信息的每次操作涉及对内核的一次系统调用。
(3)右边的两个进程有一个双方都能访问的共享内存区。每个进程一旦设置好该共享内存区,就能根本不涉及内核而访问其中的数据。共享该内存区的进程需要某种形式的同步。
注意没有任何东西限制任何IPC技术只能使用两个进程。我们讲述的技术适用于任意数目的进程。在图1-1中只展示两个进程是为了简单起见。
线程
虽然Unix系统中进程的概念已使用了很久,一个给定进程内多个线程(thread)的概念却相对较新。Posix.1线程标准(称为“Pthreads”)是于1995年通过的。从IPC角度看来,一个给定进程内的所有线程共享同样的全局变量(也就是说共享内存区的概念对这种模型来说是内在的)。然而我们必须关注的是各个线程间对全局数据的同步访问。同步尽管不是一种明确的IPC形式,但它确实伴随许多形式的IPC使用,以控制对某些共享数据的访问。
本书中我们讲述进程间的IPC和线程间的IPC。我们假设有一个线程环境,并作类似如下形式的陈述:“如果管道为空,调用线程就阻塞在它的read调用上,直到某个线程往该管道写入数据。”要是你的系统不支持线程,那你可以将该句子中的“线程”替换成“进程”,从而提供“阻塞在对空管道的read调用上”的经典Unix定义。然而在支持线程的系统上,只有对空管道调用read的那个线程阻塞,同一进程中的其余线程才可以继续执行。向该空管道写数据的工作既可以由同一进程中的另一个线程去做,也可以由另一个进程中的某个线程去做。