信號量(Semphore)
#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <fcntl.h>#include <stdlib.h>#include <string.h>#include <sys/sem.h>union semun{ int val; struct semid_ds *buf; unsigned short *arry;};static int sem_id = 0;static int set_semvalue();static void del_semvalue();static int semaphore_p();static int semaphore_v();int main(int argc, char *argv[]) { char message = 'X'; int i = 0; // 創建信號量 sem_id = semget((key_t)1234, 1, 0666|ipC_CREAT); if (argc > 1) { // 程序第一次被調用,初始化信號量 if (!set_semvalue()) { fPRintf(stderr, "Failed to initialize semaphore./n"); exit(EXIT_FAILURE); } // 設置要輸出到屏幕中的信息,及其參數的第一個字符 message = argv[1][0]; } for (i = 0; i < 10; ++i) { // 進入臨界區 if (!semaphore_p()) exit(EXIT_FAILURE); // 向屏幕中輸出數據 printf("%c", message); // 清理緩沖區,然后休眠隨機時間 fflush(stdout); sleep(rand() % 3); // 離開臨界區前再次向屏幕輸出數據 printf("%c ", message); fflush(stdout); // 離開臨界區,休眠隨機時間后繼續循環 if (!semaphore_v()) exit(EXIT_FAILURE); sleep(rand() % 2); } sleep(10); printf("/n%d finished./n", getpid()); if (argc > 1) { // 如果程序是第一次被調用,則在推出前刪除信號量 sleep(3); del_semvalue(); } exit(EXIT_SUCCESS);}static int set_semvalue(){ // 用于初始化信號量,在使用信號量前必須這樣做 union semun sem_union; sem_union.val = 1; if (semctl(sem_id, 0, SETVAL, sem_union) == -1) return 0; return 1;}static void del_semvalue(){ // 刪除信號量 union semun sem_union; if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1) fprintf(stderr, "Failed to delete semaphore./n");}static int semaphore_p(){ // 對信號量做減1操作,即等待P(sv) struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = -1; // p() sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "semaphore_p failed./n"); return 0; } return 1;}static int semaphore_v(){ // 釋放操作,使信號量變為可用,即發送信號V(sv) struct sembuf sem_b; sem_b.sem_num = 0; sem_b.sem_op = 1; // V() sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "semaphore_v failed./n"); return 0; } return 1;}
|
新聞熱點
疑難解答