|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
9 M8 O; x I+ {" }& U
信号量又称为信号灯,它是用来协调不同进程间的数据对象的,而最主要的应用是前一节的共享内存方式的进程间通信。本质上,信号量是一个计数器,它用来记录对某个资源(如共享内存)的存取状况。一般说来,为了获得共享资源,进程需要执行下列操作:3 m# J# y# V9 E- h4 z8 M- S
9 z' J4 ^1 g9 g* Y L) f+ m" I# H0 |
(1) 测试控制该资源的信号量。
* h8 A, V D: `6 [2 c" i, E( }9 T6 c/ i
(2) 若此信号量的值为正,则允许进行使用该资源。进程将进号量减1。
. c+ H; d0 V" P3 e
9 R$ R; X1 E1 V2 I3 a8 P3 ?(3) 若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1)。
1 K' n+ A4 j/ I
/ t( Y m- f) b& P: z5 v(4) 当进程不再使用一个信号量控制的资源时,信号量值加1。如果此时有进程正在睡眠等待此信号量,则唤醒此进程。( F b' Y- ?4 e6 }# h. W
& o9 P4 T6 L$ z4 Z& g, U- i维护信号量状态的是Linux内核操作系统而不是用户进程。我们可以从头文件/usr/src/linux/include /linux /sem.h中看到内核用来维护信号量状态的各个结构的定义。信号量是一个数据集合,用户可以单独使用这一集合的每个元素。要调用的第一个函数是semget,用以获得一个信号量ID。4 v! B- K1 \+ z2 r
: Y6 |. ?! Q+ J2 y2 w, _ ^2 |
#i nclude <sys/types.h>
2 @1 D( k9 u1 U+ E #i nclude <sys/ipc.h>6 V8 y* u2 y1 U% E# b! p7 Z
#i nclude <sys/sem.h>8 H2 Q6 b& J. w+ z4 q
int semget(key_t key, int nsems, int flag);+ O# z) I) A3 _3 o
1 W5 D+ t' i) s# b3 G! ~; |3 O
key是前面讲过的IPC结构的关键字,它将来决定是创建新的信号量集合,还是引用一个现有的信号量集合。nsems是该集合中的信号量数。如果是创建新集合(一般在服务器中),则必须指定nsems;如果是引用一个现有的信号量集合(一般在客户机中)则将nsems指定为0。( r% `1 `9 K4 ]5 K
2 {) @2 r u! W. B( P; h; x
sEMCtl函数用来对信号量进行操作。
9 B- D# N6 w# e; {( X# Q, u; L
F5 N4 o2 Y5 _7 ^1 J& Y3 q2 yint semctl(int semid, int semnum, int cmd, union semun arg);
! j" }! _* e' t2 z5 y; F0 P) b) Y9 ~3 T; T2 J& w6 ^' s9 ]7 N
不同的操作是通过cmd参数来实现的,在头文件sem.h中定义了7种不同的操作,实际编程时可以参照使用。
7 Q* W; t, e' i1 E& W( o
! `4 d* E |# N+ \* n _semop函数自动执行信号量集合上的操作数组。5 l% I3 b5 `' t* G, F/ ]* ~3 P
+ z0 |' _2 _5 _: A+ ~9 hint semop(int semid, struct sembuf semoparray[], size_t nops);
5 F7 h- S2 B9 l! b8 H5 i
$ w( v# M( a7 \% N# C/ S( Fsemoparray是一个指针,它指向一个信号量操作数组。nops规定该数组中操作的数量。
' ^3 A" Q4 u) E5 y% P7 F% q
: y! i4 Z9 [( y9 i; c9 W例:获取信号量状态:% S8 K( m( u! B8 m8 w9 j* h# s
) Y! e8 m. `. Ustruct semid_ds semidbuf;, Q' k: d `" _" K3 |# R
2 Y% ^* [7 l4 x( P' ?+ H# D9 qsemctl(semid, 0, IPC_STAT, &semidbuf); |
|