📄 p11-17.c
字号:
#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>int open_semaphore_set( key_t, int);void init_a_semaphore( int, int, int);int rm_semaphore(int);int semaphore_P(int);int semaphore_V(int sem_id);int main(int argc, char *argv[]){ int sem_id; int i, creat = 0; int pause_time; char *cp; /*以进程ID作为随机数种子 */ srand((unsigned int)getpid()); /* 打开/创建仅一个信号量的集合*/ sem_id = open_semaphore_set((key_t)1234, 1); if (argc > 1 && strcmp(argv[1],"1")) { /* 负责创建和删除信号量集合 */ /* 设置第一个信号量的初值为1 */ init_a_semaphore(sem_id, 0, 1); creat = 1; sleep(2); } for (i = 0; i < argc; i++) { cp = argv[i]; if (!semaphore_P(sem_id)) exit(EXIT_FAILURE); /* 关键区开始 */ printf("process %d:",getpid()); fflush(stdout); while(*cp){ printf("%c",*cp); fflush(stdout); pause_time = rand() % 3; sleep(pause_time); cp++; } printf("\n"); /* 关键区结束 */ if (!semaphore_V(sem_id)) exit(EXIT_FAILURE); pause_time = rand() % 2; sleep(pause_time); } printf("\n%d - finished\n", getpid()); if (creat == 1) { sleep(10); rm_semaphore(sem_id); } exit(EXIT_SUCCESS);}/* P操作--企图进入一关键区 */int semaphore_P(int sem_id){ struct sembuf sb; sb.sem_num = 0; sb.sem_op = -1; /* P操作-信号量值减少 */ sb.sem_flg = SEM_UNDO; /* 如果死亡,解除信号量请求*/ if (semop(sem_id, &sb, 1) == -1){ fprintf(stderr,"semaphore_P failed\n"); return(0); } return(1);}/* V操作--离开关键区 */int semaphore_V(int sem_id){ struct sembuf sb; sb.sem_num = 0; sb.sem_op = 1; /* V操作-信号量值增加 */ sb.sem_flg = SEM_UNDO; /* 如果死亡,解除信号量请求*/ if (semop(sem_id, &sb, 1) == -1){ fprintf(stderr,"semaphore_V failed\n"); return(0); } return(1);}/* 说明semun结构 */union semun { int val; struct semid_ds *buf; unsigned short *array;};/* 获得指定的信号量之值 */int get_sem_val( int sid, int semnum ){ return( semctl(sid, semnum, GETVAL, 0));}/* 给指定的信号量赋初值 */void init_a_semaphore( int sid, int semnum, int initval){ union semun semopts; semopts.val = initval; semctl( sid, semnum, SETVAL, semopts);}/* 给指定的信号量集合赋初值 */void init_all_semaphore( int sid, int val_array[]){ union semun semopts; semopts.array = val_array; semctl( sid, 0, SETALL, semopts);}/* 改变信号量集合的访问权限,权限参数必须是形如"660"的字符串 */int changemode(int sid, char *mode){ int rc; union semun semopts; struct semid_ds mysemds; /* 注意,应先使semopts.buf 指向我们自己定义的缓冲区! */ semopts.buf = &mysemds; /* 获得内部数据结构的当前值 */ if ((rc = semctl(sid, 0, IPC_STAT, semopts)) == -1) return -1; /* 改变访问权限 */ sscanf(mode, "%o", &semopts.buf->sem_perm.mode); /* 更新内部数据结构 */ return(semctl(sid, 0, IPC_SET, semopts));}/* 删除指定的信号量集合 */int rm_semaphore(int sid){ return(semctl(sid, 0, IPC_RMID,0));}int open_semaphore_set( key_t keyval, int numsems ){ int sid; if (!numsems) return(-1); if((sid = semget( keyval, numsems, IPC_CREAT | 0660 )) == -1) return(-1); else return(sid);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -