|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
# ]# ^" j$ E6 Z; ^( I- V
信号量又称为信号灯,它是用来协调不同进程间的数据对象的,而最主要的应用是前一节的共享内存方式的进程间通信。本质上,信号量是一个计数器,它用来记录对某个资源(如共享内存)的存取状况。一般说来,为了获得共享资源,进程需要执行下列操作:
& X/ @8 s' f0 U4 S( m, O7 N" t2 W2 G5 p1 w# ^9 f1 w8 w' i- R" V) G
(1) 测试控制该资源的信号量。, g2 F1 I% H( `
1 m$ @7 k$ M# e, z(2) 若此信号量的值为正,则允许进行使用该资源。进程将进号量减1。
6 t, u% S5 X+ j6 ~
. x6 x+ O6 P! ^2 K(3) 若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1)。
. Y; Q2 u% m: e G% Q/ ]6 D7 n6 X1 m) w2 X9 ~
(4) 当进程不再使用一个信号量控制的资源时,信号量值加1。如果此时有进程正在睡眠等待此信号量,则唤醒此进程。
- a; t# f& @: H3 w5 k9 V; t, l4 ^' s+ _# h) i' l) C
维护信号量状态的是Linux内核操作系统而不是用户进程。我们可以从头文件/usr/src/linux/include /linux /sem.h中看到内核用来维护信号量状态的各个结构的定义。信号量是一个数据集合,用户可以单独使用这一集合的每个元素。要调用的第一个函数是semget,用以获得一个信号量ID。
. A+ n% Y: U. p5 h, r6 l# h1 t {6 [2 A6 N4 W v
#i nclude <sys/types.h>4 i: W; d2 ~2 @0 `
#i nclude <sys/ipc.h>/ [6 q4 V$ p2 r9 @( P8 m% w
#i nclude <sys/sem.h>
1 o& O% ]; @$ B int semget(key_t key, int nsems, int flag);
$ S) E! ]* ~9 a! k$ _; p( g$ }
* s. y( b$ }4 E9 j S. f. e4 u5 S: dkey是前面讲过的IPC结构的关键字,它将来决定是创建新的信号量集合,还是引用一个现有的信号量集合。nsems是该集合中的信号量数。如果是创建新集合(一般在服务器中),则必须指定nsems;如果是引用一个现有的信号量集合(一般在客户机中)则将nsems指定为0。
7 o/ l3 p3 Z* p' g8 o! A& d$ e2 \% C' k8 a2 u, P6 w: D
sEMCtl函数用来对信号量进行操作。
; L9 j) b: p6 t$ U# _, a( \! I3 ^
int semctl(int semid, int semnum, int cmd, union semun arg);
) B5 K1 g2 x6 v- b. O9 M0 A, h
) U- M/ o' M# D7 [不同的操作是通过cmd参数来实现的,在头文件sem.h中定义了7种不同的操作,实际编程时可以参照使用。) }; p. U% I: r* u) P' Z
1 J2 m# X8 E$ r+ `
semop函数自动执行信号量集合上的操作数组。4 x7 d2 H% Z2 ?# ^
$ G8 V2 C$ }6 }1 `1 B0 o B2 s2 Q
int semop(int semid, struct sembuf semoparray[], size_t nops);" [3 L, i2 H1 z
) E; g& q7 ^# N* e' ^& Qsemoparray是一个指针,它指向一个信号量操作数组。nops规定该数组中操作的数量。4 n! \; n2 U) s! c$ [( r0 P* h
: H- n4 t' [# H2 Z+ X0 f
例:获取信号量状态:0 q0 V, p; e. D% d2 L
K/ [, I$ f8 H( C
struct semid_ds semidbuf;+ z& W, e/ `- k3 q
, b. D8 J0 _. Y1 k% q4 B
semctl(semid, 0, IPC_STAT, &semidbuf); |
|