SystemV信号量与POSIX信号量简介

转载自:http://linuxperf.com/?p=25
对原文做了一些删减和结构上的优化。

SystemV 信号量

SystemV 信号量是内核对象,由内核统一管理; 它的存续不依赖于进程,即使进程退出也仍然存在。

  • semget(2): 向内核提出申请,内核根据需要创建新的信号量或关联已存在的信号量,每组信号量都有唯一的ID标识,可以被多个进程共享。
  • semop(2) 或 semtimedop(2): PV操作。
  • semctl(2): 删除信号量。(进程即使不存在,信号量也存在于内核中,除非调用此函数)

有两条命令用来管理System V 信号量:

  • ipcs(1): ipcs -s 用于查看,
  • ipcrm(1): ipcrm -s 用于删除。

POSIX 信号量

POSIX信号量是基于系统调用 futex(2) 实现的。
POSIX信号量分为两类:无名信号量(unnamed semaphore) 和 有名信号量(named semaphore).

  • sem_wait(3)和sem_post(3): POSIX信号量的PV操作,对无名信号量和有名信号量都一样。

POSIX 有名信号量

有名信号量与 System V 信号量类似,它也是由内核统一管理的,因此有名信号量的存续也是由内核决定的,与进程是否退出无关。
SystemV信号量是用ID作标识;而POSIX有名信号量用名字作标识。
有名信号量的名字有点像文件名,必须是以”/”开头的字符串,但不能包含字符”.”

  • sem_open(3): 创建或打开有名信号量
  • sem_unlink(3): 删除有名信号量

在Linux系统上,有名信号量跟共享内存一样,会在/dev/shm 目录下产生文件,管理有名信号量通过这些文件进行,查看的命令如下:

$ ls -al /dev/shm/sem.*
-rw------- 1 auniyal auniyal 16 2011-08-09 15:59 /dev/shm/sem.mysem
-rw------- 1 auniyal auniyal 16 2011-08-09 16:29 /dev/shm/sem.mysem1
...

删除的命令如下:

$ rm /dev/shm/sem.mysem

POSIX无名信号量

无名信号量是基于用户空间内存的。

  • sem_init(3): 创建无名信号量,调用参数中需要指定放置信号量的内存地址,这个地址可以是私有内存,也可以是共享内存。

如果要在多个进程之间共享无名信号量的话,就必须使用共享内存。
在实践中,无名信号量一般用于线程之间、或者父子进程之间,否则编程有点麻烦:因为要事先约定好无名信号量的地址才行。

由于无名信号量建立在user memory上,它的存续与内存的存续直接相关:

  • 如果无名信号量位于进程的私有内存(比如进程的全局变量),那么当该进程终止时无名信号量也会消失;
  • 如果无名信号量是在共享内存区中,那么只要该共享内存区还存在,该信号量就存在,而与进程是否中止没有关系。
  • 好像没有命令用来查看或管理无名信号量。

比较 System V 信号量 和 POSIX 信号量

  • POSIX信号量的API是库函数,而SystemV信号量的API是系统调用(system calls)。
  • 用strace(1)跟踪一下,会看到SystemV信号量使用的系统调用是semget(2)/semctl(2)/semop(2)等,而POSIX信号量使用的系统调用是futex(2)
  • 使用POSIX信号量的程序需要链接librt.xxx库,编译时使用-lrt参数。

(完)

你可能感兴趣的:(#,Linux编程,linux)