Linux下的信号量

时间:2022-06-20 04:43:09
首先,什么是信号量?
  信号量的本质是一种数据操作锁,它本身不具有数据交换的功能,而是通过控制其他的通信资源(文件,外部设备)来实现进程间通信,它本身只是一种外部资源的标识。信号量在此过程中负责操作的互斥、同步等功能。

//Makefile commh=comm.h src=sem.c comm.c dst=sem cc=gcc $(dst):$(src) $(commh) $(cc) -o $@ $^ .PHONY:clean clean: rm -rf $(dst) //comm.h #ifndef __COMM_H__ #define __COMM_H__ #include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/sem.h> #define PATHNAME "." #define PROJID 0666 union SemUn { int val; struct semid_ds *buf; unsigned short *array; struct seminfo *__buf; }; int creatSemSet(int nums); int getSemSet(); int initSemSet(int semid,int which); int P(int semid); int V(int semid); int destorySemSet(int semid); #endif //comm.c #include"comm.h" static int commSemSet(int nums,int flags) { key_t _k=ftok(PATHNAME,PROJID); if(_k==-1) { perror("ftok"); return -1; } int semid=semget(_k,nums,flags); if(semid<0) { perror("semget"); return -1; } return semid; } int creatSemSet(int nums) { return commSemSet(nums,IPC_CREAT | IPC_EXCL | 0666); } int getSemSet() { return commSemSet(0,0); } int initSemSet(int semid,int which) { union SemUn _SemUn; _SemUn.val=1; if(semctl(semid,which,SETVAL,_SemUn)<0) { perror("semctl"); return -1; } return 0; } static int SemOp(int semid,int op,int which) { struct sembuf buf[1]; buf[0].sem_op=op; buf[0].sem_num=which; if(semop(semid,buf,1)==-1) { perror("semop"); return -1; } return 0; } int P(int semid) { return SemOp(semid,-1,0); } int V(int semid) { return SemOp(semid,1,0); } int destorySemSet(int semid) { if(semctl(semid,0,IPC_RMID,NULL)==-1) { perror("semctl"); return -1; } return 0; } //sem.c #include"comm.c" int main() { int semid=creatSemSet(1); initSemSet(semid,0); pid_t id=fork(); if(id==0) { int semid=getSemSet(); while(1) { P(semid); //进入临界区 printf("A"); fflush(stdout); usleep(10031); printf("A"); fflush(stdout); usleep(10021); V(semid); } } else { while(1) { P(semid); //进入临界区 printf("B"); fflush(stdout); usleep(10051); printf("B"); fflush(stdout); usleep(10003); V(semid); } } destorySemSet(semid); }