Unix Network Programming 2

卷二对Unix各种进程间通信(IPC)方法做了介绍。

IPC方法主要有(这里只列出POSIX IPC):

  1. 管道&FIFO(有名管道)
  2. 消息队列
  3. 锁与条件变量
  4. 信号量
  5. 共享内存

其中POSIX消息队列实际运用很少,就不在这里讲解了。

IPC的持续性

将IPC的持续性分为3种:

  1. 随进程,如管道、非共享内存区互斥锁和条件变量
  2. 随内核,如有名信号量、共享内存
  3. 随文件

管道&FIFO

管道适合进程进行少量数据的传递。

使用pipe函数创建管道,然后使用fork复制进程,子进程/父进程关闭读/写管道,最后使用write/read进行数据读写。

FIFO是有名管道,可用于无亲缘关系的进程之间进行通信。

如果write大小小雨PIPE_BUF,则write操作具有原子性。

锁和条件变量

锁用来控制临界区访问,而条件变量用于等待条件。

条件变量在获取锁后,使用pthread_cond_wait会释放锁并等待条件满足时被唤醒。

为了防止虚假唤醒,条件变量被唤醒时需要监测条件是否满足

1
2
3
while (!is_condition_satisfied) {
pthread_cond_wait(&cond, &mutex);
}

线程取消带来的死锁问题

pthread_cond_wait是线程取消点(cancellation point)。在阻塞在pthread_cond_wait时线程被取消将导致该线程重新获得锁,必须使用线程清理程序pthread_cleanup_pushpthread_cleanuppop将锁释放掉。

信号量

锁可以看作只有0/1的信号量,信号量可以存储一个整形的状态值,可以在多个进程间共享。

共享内存

共享内存是最快的IPC方式。主要函数:

  1. mmap,映射文件到进程地址空间。可以使用ANON属性避免文件创建。
  2. munmap, msync
  3. POSIX共享内存区函数,shm_open等