C语言进程通过信号量进入临界区
来源:互联网 发布:mysql存储过程的数组 编辑:程序博客网 时间:2024/06/05 05:15
#include<sys/sem.h>#include<unistd.h>#include<stdio.h>#include<stdlib.h>int res; // 返回结果int sem_id; //信号标识符union semun //定义semun,不同的系统可能不同,需要自己定义{ int val; struct semid_ds *buf; unsigned short *array; struct seminfo *__buf;};void sem_setval() //初始化信号量{ union semun sem_union; sem_union.val=1; //信号量的初始值 res=semctl(sem_id,0,SETVAL,sem_union); //初始化信号量 if(-1==res) { perror("semctl failed \n"); exit(0); }}void sem_remove() //销毁信号量{ union semun sem_union; res=semctl(sem_id,0,IPC_RMID,sem_union); //销毁信号量 if(-1==res) { perror("sem remove control fail\n"); exit(0); }}void sem_p() //减少信号量{ struct sembuf sema_buff; sema_buff.sem_num=0; //信号编号,信号量编号从0开始 sema_buff.sem_op=-1; //对信号量的操作值,使信号量减1 sema_buff.sem_flg=SEM_UNDO; //让系统跟进这个信号量的修改 res=semop(sem_id,&sema_buff,1);//对信号量操作,如果信号量为0则等待。 if(-1==res) { perror("semop failed \n"); exit(0); }}void sem_v() //增加信号量{ struct sembuf sema_buff; sema_buff.sem_num=0; sema_buff.sem_op=1; //使信号量加1 sema_buff.sem_flg=SEM_UNDO; res=semop(sem_id,&sema_buff,1); if(res==-1) { perror("semov failed\n"); exit(0); }}int main(){ char CHR; //这是本程序的临界变量,即一次只能一个进程或线程访问 sem_id=semget((key_t)1024,1,0666|IPC_CREAT); if(sem_id<=0) { perror("semget failed\n"); exit(0); } sem_setval(); res=fork(); //创建新进程 if(res==-1) { perror("fork error\n"); exit(0); } if(res==0) //子进程 { int i=0; CHR='O'; for(i;i<=10;i++) { sem_p(); printf("%c",CHR); fflush(stdout); printf("%c",CHR); fflush(stdout); sleep(1); sem_v(); } exit(0); }else{ //父进程 int i=0; CHR='X'; for(i;i<=10;i++) { sem_p(); printf("%c",CHR); printf("%c",CHR); fflush(stdout); sleep(1); sem_v(); } wait(NULL); sem_remove(); exit(0); }}