2010年3月26日 星期五

IPC facility - Semaphore

Semaphore

#include sys/types.h
#include sys/ipc.h
#include sys/sem.h

int semget ( key_t key, int num_sems, int sem_flags );
key在這邊是要做 IPC 的各個 process 之間共有的一個鍵值 (key value)
key需要相同,才能確保 semget 會回傳代表共用 semaphore 的 sem_id
每個 process 都會拿到只供自己使用的 sem_id 但是其指向的是共用的 semaphore
後文所述另外兩種 IPC facilities 也是採用同樣的原理

num_sems 表示需要使用的 semaphore 數量,一般最常見的值是 1
表示只使用一個 semaphore,如有需要也可以使用多個,會以陣列表示
*所以一個 sem_id 可以表示一個 semaphore 也可以表示一組 semaphores

sem_flags 可以設定類似檔案擁有的權限值,如 0666 這種值
另外可與 IPC_CREAT 或 IPC_EXCL 使用 bitwise OR 運算結合
IPC_CREAT: create a semaphore
IPC_EXCL: exclusive action

[example]
key_t key = (key_t) 54321;
int sem_id = semget ( key, 1, 0644 | IPC_CREAT );



int semop ( int sem_id, struct sembuf* sem_ops, size_t num_sem_ops );
sem_id 是由 semget 回傳的 semaphore identifier
在此表示指定要使用的 semaphore

struct sembuf {
short sem_num; /* index */
short sem_op; /* operations on semaphore */
short sem_flg; /* SEM_UNDO */
}

num_sem_ops 表示 sem_ops 陣列的 size

[example]
/* P action [wait] */
struct sembuf sembuf_p;
sembuf_p.sem_num = 0;
sembuf_p.sem_op = -1; /* for P( ) action */
sembuf_p.sem_flg = SEM_UNDO;

/* V action [signal] */
struct sembuf sembuf_v;
sembuf_v.sem_num = 0;
sembuf_v.sem_op = 1; /* for V( ) action */
sembuf_v.sem_flg = SEM_UNDO;

semop( sem_id, &sembuf_p, 1 );



int semctl ( int sem_id, int sem_num, int command, ... );
sem_id 是由 semget 回傳的 semaphore identifier
在此表示指定要使用的 semaphore

sem_num 用來表示 semaphore number,用在 semaphore 陣列
其值通常是 0,表示第一個而且是唯一的 semaphore ( 單一 semaphore 的情況 )

command 表示要採取的 action,主要使用的是 SETVAL 以及 IPC_RMID
SETVAL 是拿來設定值,會用到第四個參數 union semnu 中的 val 成員
IPC_RMID 是用來移除 semaphore

第四個參數,如果有設定的話,是一個 C union,定義如下

union semnu{
int val;
struct semid_ds* buf;
unsigned short array;
}

[example]
union semun sem_union;
sem_union.val = 1;
semctl ( sem_id, 0, SETVAL, sem_union );
------
semctl ( sem_id, 0, IPC_RMID, sem_union );



[Reference]
Begining Linux Programming 4th edition
Chapter 14 Semaphore, Shared Memory, and Message Queues

沒有留言:

張貼留言