|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
: E+ v( w$ Z0 l+ S* p信号量又称为信号灯,它是用来协调不同进程间的数据对象的,而最主要的应用是前一节的共享内存方式的进程间通信。本质上,信号量是一个计数器,它用来记录对某个资源(如共享内存)的存取状况。一般说来,为了获得共享资源,进程需要执行下列操作:
& X) {% |: p; P# h G0 [- Z' v
) ?8 i( E# H( F0 B(1) 测试控制该资源的信号量。. i ?/ x9 s* y- _0 e! W
2 H1 K; E( R/ L8 L) ~/ J9 v7 A. I
(2) 若此信号量的值为正,则允许进行使用该资源。进程将进号量减1。
5 }8 k+ Q( S _' e. l
6 V5 a) ^1 R- g: G8 t% \" o(3) 若此信号量为0,则该资源目前不可用,进程进入睡眠状态,直至信号量值大于0,进程被唤醒,转入步骤(1)。
0 n) D, ?, K6 O& k1 L! _4 s7 v" J, }+ H
(4) 当进程不再使用一个信号量控制的资源时,信号量值加1。如果此时有进程正在睡眠等待此信号量,则唤醒此进程。8 h0 D# s7 D) d
, z* q3 Y% ~. ~, w( D, U
维护信号量状态的是Linux内核操作系统而不是用户进程。我们可以从头文件/usr/src/linux/include /linux /sem.h中看到内核用来维护信号量状态的各个结构的定义。信号量是一个数据集合,用户可以单独使用这一集合的每个元素。要调用的第一个函数是semget,用以获得一个信号量ID。* ]9 V* Q: u2 \3 B
9 o% I. X* r' R8 K/ l/ [ w3 B#i nclude <sys/types.h>9 n/ s9 c( ]0 {/ }$ P
#i nclude <sys/ipc.h>
- @8 n' R. ~# U* |3 j #i nclude <sys/sem.h>
2 s+ i! ~' p- }6 o3 W$ f9 |. Z int semget(key_t key, int nsems, int flag);' E4 W+ w7 w( ^5 u S
' B1 u, G/ @$ _/ X
key是前面讲过的IPC结构的关键字,它将来决定是创建新的信号量集合,还是引用一个现有的信号量集合。nsems是该集合中的信号量数。如果是创建新集合(一般在服务器中),则必须指定nsems;如果是引用一个现有的信号量集合(一般在客户机中)则将nsems指定为0。4 K7 t* [# x' f* S: ^) R
9 G/ N7 e! V9 m0 k- U- I
sEMCtl函数用来对信号量进行操作。
9 S* f9 T# ]; ~9 E0 z
" Y0 B {+ T/ B9 h( q$ j7 ~. W! `int semctl(int semid, int semnum, int cmd, union semun arg);
( e2 \. l5 ^$ t3 |3 I/ n* G) d" G5 } Q$ ^2 t% n1 D; E
不同的操作是通过cmd参数来实现的,在头文件sem.h中定义了7种不同的操作,实际编程时可以参照使用。* O2 W- l3 Y7 |
( _" q: O! [- \3 T5 |; X3 G5 }+ ]semop函数自动执行信号量集合上的操作数组。) d3 w$ E6 T' l3 f) B
C! g, h4 o/ i6 k
int semop(int semid, struct sembuf semoparray[], size_t nops);
0 H" |3 i) v2 q& _, A$ B
7 E* G1 |2 x* S6 I) ssemoparray是一个指针,它指向一个信号量操作数组。nops规定该数组中操作的数量。7 R( S# z& ]' ~9 ]8 O0 a
6 l8 S o3 C. d6 W8 x: M6 n
例:获取信号量状态:' T' a+ D8 v. [! |, K/ L
/ Q$ z' k7 c( N S+ M) Istruct semid_ds semidbuf;
" ]( V! R4 {0 p5 R! D# v
- `* z( _& M7 w: N: isemctl(semid, 0, IPC_STAT, &semidbuf); |
|