|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
5 q' o# z2 v- L4 i
信号量又称为信号灯,它是用来协调不同进程间的数据对象的,而最主要的应用是前一节的共享内存方式的进程间通信。本质上,信号量是一个计数器,它用来记录对某个资源(如共享内存)的存取状况。一般说来,为了获得共享资源,进程需要执行下列操作:; s/ e9 w% L. r0 k; N
+ K8 i' i1 @* r' A(1) 测试控制该资源的信号量。( r- Y( S) ]% E* |
3 S. n9 d. x7 w, [2 q, Y+ i
(2) 若此信号量的值为正,则允许进行使用该资源。进程将进号量减1。$ i; q _$ _1 c
w+ ` E, `. f v6 V# W(3) 若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1)。/ o6 Q: V# A! L0 q, O. ]
+ f$ ~& m$ S n7 s(4) 当进程不再使用一个信号量控制的资源时,信号量值加1。如果此时有进程正在睡眠等待此信号量,则唤醒此进程。' V* H3 ^+ X3 M# r. ]5 S# S r
- P- R- [2 U' z7 n7 l1 O3 t
维护信号量状态的是Linux内核操作系统而不是用户进程。我们可以从头文件/usr/src/linux/include /linux /sem.h中看到内核用来维护信号量状态的各个结构的定义。信号量是一个数据集合,用户可以单独使用这一集合的每个元素。要调用的第一个函数是semget,用以获得一个信号量ID。+ b, S9 E" r8 m$ k" C- `) @- U6 q
( ?/ C9 i+ J! g+ g1 r
#i nclude <sys/types.h>, T% v& d# w0 e0 ] [+ l
#i nclude <sys/ipc.h>
% z; C' y! w5 F2 b. C #i nclude <sys/sem.h>
4 a* p4 J g8 J/ b int semget(key_t key, int nsems, int flag);: m5 h, w9 W3 w7 W0 b3 e
+ M# J1 F/ L3 B( Z
key是前面讲过的IPC结构的关键字,它将来决定是创建新的信号量集合,还是引用一个现有的信号量集合。nsems是该集合中的信号量数。如果是创建新集合(一般在服务器中),则必须指定nsems;如果是引用一个现有的信号量集合(一般在客户机中)则将nsems指定为0。
% i8 v+ B; _! g, x/ c/ D
9 ]6 ]) Q6 ]0 _9 u9 M4 gsEMCtl函数用来对信号量进行操作。
1 ? \5 ]( w9 A1 T7 W# m! ]+ P* ^8 O/ w" i2 [
int semctl(int semid, int semnum, int cmd, union semun arg);2 [2 y6 I% F! G0 i8 n, Y- L; x6 r' v
v6 [ q, ~& p' y6 b) z0 g不同的操作是通过cmd参数来实现的,在头文件sem.h中定义了7种不同的操作,实际编程时可以参照使用。
( m& }; P8 L- @; g% g3 U* k! R( T# F, B7 _
semop函数自动执行信号量集合上的操作数组。& a) L" h) J' T0 C5 Y; L$ K) P w8 C
' ~9 a2 ~( [7 Sint semop(int semid, struct sembuf semoparray[], size_t nops);
5 }9 w+ @9 Z5 Q! C; d) F1 D- t2 ]/ I
semoparray是一个指针,它指向一个信号量操作数组。nops规定该数组中操作的数量。
- S. R3 i: g, g m
- {; h, W% N# n _2 I/ Z例:获取信号量状态:
- n3 |0 ?9 p: _, A9 U; e5 b1 q5 T! {% j9 @/ ^
struct semid_ds semidbuf;
# D* R- a% g1 K3 H
6 j2 b6 ] @/ J) |1 n2 Y: jsemctl(semid, 0, IPC_STAT, &semidbuf); |
|