|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
4 i V9 g2 }& h
信号量又称为信号灯,它是用来协调不同进程间的数据对象的,而最主要的应用是前一节的共享内存方式的进程间通信。本质上,信号量是一个计数器,它用来记录对某个资源(如共享内存)的存取状况。一般说来,为了获得共享资源,进程需要执行下列操作:5 f4 _% L. P' f
9 p# }2 g! J! g' z) f(1) 测试控制该资源的信号量。
( s% a; a, u% i0 s/ v: k" a, y) a5 _% `; [( z9 g$ @
(2) 若此信号量的值为正,则允许进行使用该资源。进程将进号量减1。
9 {- F. ]2 Z" K- Z$ E$ S2 ]3 R* V& D
(3) 若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1)。
6 H3 t8 @4 Q0 @, Y; o
8 _) Q$ W1 \# H8 s. Z0 n4 |(4) 当进程不再使用一个信号量控制的资源时,信号量值加1。如果此时有进程正在睡眠等待此信号量,则唤醒此进程。
7 @3 e/ o; w6 a0 \/ A, J3 m2 j% `7 ^4 M. c
维护信号量状态的是Linux内核操作系统而不是用户进程。我们可以从头文件/usr/src/linux/include /linux /sem.h中看到内核用来维护信号量状态的各个结构的定义。信号量是一个数据集合,用户可以单独使用这一集合的每个元素。要调用的第一个函数是semget,用以获得一个信号量ID。
7 Q6 j; l# ~( ]5 w& e
$ n0 l8 E1 H" z5 t#i nclude <sys/types.h>' L. [- y# D6 u) j- s3 s, N
#i nclude <sys/ipc.h>0 u+ T$ K% B4 L- @9 ~& o% N
#i nclude <sys/sem.h>" k( }. C4 Z" G2 ]' K
int semget(key_t key, int nsems, int flag);0 e& t2 P, d1 e0 v# }
; |7 W# b0 _- p4 s2 h+ F
key是前面讲过的IPC结构的关键字,它将来决定是创建新的信号量集合,还是引用一个现有的信号量集合。nsems是该集合中的信号量数。如果是创建新集合(一般在服务器中),则必须指定nsems;如果是引用一个现有的信号量集合(一般在客户机中)则将nsems指定为0。" A/ N$ S6 L3 X% @) a6 o
+ b( A1 y6 t# ?, D9 j+ ZsEMCtl函数用来对信号量进行操作。5 o: _9 D- }9 D
x! Q; ^4 l4 |% pint semctl(int semid, int semnum, int cmd, union semun arg);
. F1 g) K+ {4 u7 t- T8 G! g* Y3 K# e- T, I
不同的操作是通过cmd参数来实现的,在头文件sem.h中定义了7种不同的操作,实际编程时可以参照使用。
# ^9 X' F: O1 W( ?" |& ?* z" b' T+ {9 z$ g1 g4 ^3 v. ^2 @4 @2 n. u
semop函数自动执行信号量集合上的操作数组。( T) V5 y" p* R) T; D
2 u0 W# m- B2 W( z/ y8 q' ~% `0 x1 x
int semop(int semid, struct sembuf semoparray[], size_t nops);) e7 H* R+ X" G" V6 C+ w/ U5 W
" X7 @8 V6 y& u2 l5 gsemoparray是一个指针,它指向一个信号量操作数组。nops规定该数组中操作的数量。
( ~) d9 N0 ?1 l- L T* ~
; I8 p/ `; p3 G2 L- B1 C例:获取信号量状态:1 B) k: m9 w7 p7 W& z
5 @( Z; [. p- O* A# rstruct semid_ds semidbuf;
3 Z7 P1 x% K% V; Z# e) C& M/ O
# }) i$ o C0 E. wsemctl(semid, 0, IPC_STAT, &semidbuf); |
|