信号量

来源:互联网 发布:网络远程 编辑:程序博客网 时间:2024/06/15 11:19
struct sembuf{/* 要获取/释放的信号量的编号,从0开始 */unsigned short sem_num;/* 为正时表示释放信号量,为负时表示获取信号量 */short sem_op; /*信号量操作标志,可能的选择有两种:IPC_NOWAIT,对信号量的操作不能满足时,semop()不会阻塞,而是立即返回,并且设定错误信息。SEM_UNDO,程序结束时(不论正常或不正常),保证信号量会被重设为semop()调用前的值。这样做的目的在于避免程序在异常情况下结束时未将锁定的资源解锁,造成该资源永远锁定*/short sem_flg; };

#include<stdio.h>#include<sys/types.h>#include<sys/ipc.h>#include<sys/sem.h>#include<stdlib.h>#include<math.h>#include<errno.h>/*父进程先获取信号量,子进程获取的时候阻塞父进程释放信号量,并唤醒子进程父进程最后删除信号量集合*/int main(int argc, char * argv[]){/*让系统生成一个IPC key*/key_t ipc_key;ipc_key=ftok("./sem.c", 1);if(ipc_key<0){printf("ftok error!\n");exit(0);}/*获取信号量集合,如果不存在则创建*//*信号量集合中有1个信号量*/int semset_id;semset_id=semget(ipc_key, 1, IPC_CREAT|0755);if(semset_id<0){printf("semget error!\n");exit(0);}printf("semset_id = %d\n", semset_id);/*设置这个信号量的值为1*/semctl(semset_id, 0, SETVAL, 1);/*创建子进程*/int pid;pid=fork();if(pid<0){printf("fork error!\n");exit(0);}else if(pid==0){/*先确保父进程获取了信号量*/sleep(1);/*获取信号量,此时会阻塞,直到父进程释放了信号量被唤醒*/struct sembuf get_op;get_op.sem_num=0;get_op.sem_op=-1;get_op.sem_flg=SEM_UNDO;if(semop(semset_id, &get_op, 1)<0){printf("semop error!\n");exit(0);}printf("Child get the semaphore.\n");exit(0);}else{/*在父进程中获取信号量*/struct sembuf get_op;get_op.sem_num=0;get_op.sem_op=-1;get_op.sem_flg=SEM_UNDO;if(semop(semset_id, &get_op, 1)<0){printf("semop error!\n");exit(0);}printf("Father get the semaphore.\n");/*sleep*/sleep(5);/*在父进程中释放信号量*//*此时会唤醒子进程*/struct sembuf release_op;release_op.sem_num=0;release_op.sem_op=1;get_op.sem_flg=SEM_UNDO;if(semop(semset_id, &release_op, 1)<0){printf("semop error!\n");exit(0);}printf("Father realease the semaphore.\n");/*等待子进程执行完成*/wait(NULL);/*删除信号量集合*/semctl(semset_id, 0, IPC_RMID, 0);exit(0);}return 0;}

原创粉丝点击