diff --git a/notes/计算机操作系统.md b/notes/计算机操作系统.md index 2cb0616c..873545cb 100644 --- a/notes/计算机操作系统.md +++ b/notes/计算机操作系统.md @@ -819,49 +819,59 @@ void test(i) { // 尝试拿起两把筷子 进程通信是一种手段,而进程同步是一种目的。也可以说,为了能够达到进程同步的目的,需要让进程进行通信,传输一些进程同步所需要的信息。 -### 1. 信号量 +### 1. 管道 -在进程同步中介绍的信号量也属于进程通信的一种方式,但是属于低级别的进程通信,因为它传输的信息非常小。 +管道是通过调用 pipe 函数创建的,fd[0] 用于读,fd[1] 用于写。 -### 2. 消息传递 +```c +#include +int pipe(int fd[2]); +``` -操作系统提供了用于通信的通道(Channel),进程可以通过读写这个通道进行通信。 +它具有以下限制: -

+- 只支持半双工通信(单向传输); +- 只能在父子进程中使用。 -**(一)管道** +

-写进程在管道的尾端写入数据,读进程在管道的首端读出数据。管道提供了简单的流控制机制,进程试图读空管道时,在有数据写入管道前,进程将一直阻塞。同样地,管道已经满时,进程再试图写管道,在其它进程从管道中移走数据之前,写进程将一直阻塞。 +### 2. FIFO -Linux 中管道通过空文件实现。 +也称为命名管道,去除了管道只能在父子进程中使用的限制。 -管道有三种: +```c +#include +int mkfifo(const char *path, mode_t mode); +int mkfifoat(int fd, const char *path, mode_t mode); +``` -- 普通管道:有两个限制,一是只能单向传输;二是只能在父子进程之间使用; -- 流管道:去除第一个限制,支持双向传输; -- 命名管道:去除第二个限制,可以在不相关进程之间进行通信。 +FIFO 常用于客户-服务器应用程序中,FIFO 用作汇聚点,在客户进程和服务器进程之间传递数据。 -

+

-**(二)消息队列** +### 3. 消息队列 -消息队列克服了信号量传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。 +相比于 FIFO,消息队列具有以下优点: -

+- 消息队列可以独立于读写进程存在,从而避免了 FIFO 中同步管道的打开和关闭时可能产生的困难; +- 避免了 FIFO 的同步阻塞问题,不需要进程自己提供同步方法; +- 读进程可以根据消息类型有选择地接收消息,而不像 FIFO 那样只能默认地接收。 -**(三)套接字** +### 4. 信号量 -套接字也是一种进程间通信机制,与其它通信机制不同的是,它可用于不同机器间的进程通信。 +它是一个计数器,用于为多个进程提供对共享数据对象的访问。 -

+### 5. 共享存储 -### 3. 共享内存 +允许多个进程共享一个给定的存储区。因为数据不需要在进程之间复制,所以这是最快的一种 IPC。 -操作系统建立一块共享内存,并将其映射到每个进程的地址空间上,进程就可以直接对这块共享内存进行读写。 +需要使用信号量用来同步对共享存储的访问。 -共享内存是最快的进程通信方式。 +多个进程可以将同一个文件映射到它们的地址空间从而实现共享内存。另外 XSI 共享内存不是使用文件,而是使用使用内存的匿名段。 -

+### 6. 套接字 + +与其它通信机制不同的是,它可用于不同机器间的进程通信。 # 三、死锁 diff --git a/pics/2ac50b81-d92a-4401-b9ec-f2113ecc3076.png b/pics/2ac50b81-d92a-4401-b9ec-f2113ecc3076.png new file mode 100644 index 00000000..173ce970 Binary files /dev/null and b/pics/2ac50b81-d92a-4401-b9ec-f2113ecc3076.png differ diff --git a/pics/53cd9ade-b0a6-4399-b4de-7f1fbd06cdfb.png b/pics/53cd9ade-b0a6-4399-b4de-7f1fbd06cdfb.png new file mode 100644 index 00000000..2666f9c2 Binary files /dev/null and b/pics/53cd9ade-b0a6-4399-b4de-7f1fbd06cdfb.png differ