信号量(sem)

来源:互联网 发布:凸轮弹簧机编程 编辑:程序博客网 时间:2024/05/17 01:29

代码:

comm.h:

#ifndef _MYSEM_#define _MYSEM_#include <stdio.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/sem.h>#define _PATH_ "."#define _PROJ_ID_ 0x0603typedef union semun {int val;    /* Value for SETVAL */struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */unsigned short  *array;  /* Array for GETALL, SETALL */struct seminfo  *__buf;  /* Buffer for IPC_INFO (Linux-specific) */}semun_t;int create_sem(int nsems);int get_sem(int nsems);int init_sem(int sem_id,int which,int init_val);int p_sem(int sem_id,unsigned short which);//-1int v_sem(int sem_id,unsigned short which);//+1int destroy_sem(int sem_id);#endif

comm.c:

#include "comm.h"static int com_sem(int nsems,int flag){key_t key = ftok(_PATH_,_PROJ_ID_);if( key < 0 ){perror("ftok");return -1;}int sem_id = semget(key,nsems,flag);//创建信号量if(sem_id < 0){perror("semget");return -2;}return sem_id;}int creat_sem(int nsems){int flag = IPC_CREAT | IPC_EXCL | 0666;return com_sem(nsems,flag);}int get_sem(int nsems){int flag = IPC_CREAT;return com_sem(nsems,flag);}static int com_semop(int sem_id,unsigned short which,short op){//对哪个信号量集中的哪一个信号进行op指定的操作struct sembuf semb[1];//只考虑二元信号量,所以只有一个元素semb[0].sem_num = which;semb[0].sem_op = op;//进行什么操作是由op说了算semb[0].sem_flg = 0;//UNDO,若一个进程在临界区崩溃了,那么flag就维护信号量,把信号量恢复if(semop(sem_id,semb,1) < 0){perror("semop");return -1;}return 0;}int p_sem(int sem_id,unsigned short which){//进行p操作int op = -1;return com_semop(sem_id,which,op);}int v_sem(int sem_id,unsigned short which){//进行v操作int op = 1;return com_semop(sem_id,which,op);}int init_sem(int sem_id,int which,int init_val){semun_t sem_val;sem_val.val = init_val;int ret = semctl(sem_id,which,SETVAL,sem_val);//初始化信号量if(ret < 0){perror("semct");return -1;}return 0;}int destory_sem(int sem_id){int ret = semctl(sem_id,0,IPC_RMID);//0是指定的信号量,此处讨论的是二元信号量if(ret < 0){perror("semctl");return -1;}printf("\ndestroy success\n");return 0;}
sem_stdout.c:(父子进程互斥访问stdout)

#include "comm.h"int main(){int f_sem_id = creat_sem(1);//使用互斥信号量(二元信号量)父进程先获取信号量init_sem(f_sem_id,0,1);//信号量从下标0开始,被初始化为1pid_t id = fork();if( id == 0){//childint c_sem_id = get_sem(1);int count = 3;while(1){p_sem(c_sem_id,0);//对第一个信号量进行P操作printf("A");fflush(stdout);sleep(rand()%3);printf("A");fflush(stdout);sleep(rand()%3);v_sem(c_sem_id,0);//对第一个信号量进行V操作count--;if(count == 0){break;}}}else{//fatherint count = 3;while(1){p_sem(f_sem_id,0);printf("B");fflush(stdout);sleep(rand()%3);printf("B");fflush(stdout);sleep(rand()%3);v_sem(f_sem_id,0);count--;if(count == 0){break;}}}//sleep(3);wait(NULL);destory_sem(f_sem_id);return 0;}

运行结果:



0 0
原创粉丝点击