信号量的一些实战思路和代码
一 信号量的一些概念和理解
首先我们要先知道什么是临界资源。多道程序系统中存在许多进程,它们共享各种资源,然而有很多资源一次只能供一个进程使用。一次仅允许一个进程使用的资源称为临界资源。许多物理设备都属于临界资源,如输入机、打印机、磁带机等。
因为我们IPC进程间的通信,都是能够数据的交互。但是信号量却不能数据的交互。他的作用类似于钥匙和锁的关系。临界资源一次只能供一个进程使用,就相当于一个房间里,只能有一个人使用,信号量就是一把钥匙,有人拿钥匙进去房间里,其他进程想进去就得在房间外面等待,等到里面的人出来,把钥匙放入,才能轮到下一个,信号量在这个过程中扮演的就是钥匙的角色。
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
// int semget(key_t key, int nsems, int semflg);
// int semctl(int semid, int semnum, int cmd, ...);
// int semop(int semid, struct sembuf *sops, unsigned nsops);
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) */
};
void pGetKey(int id)
{
struct sembuf set;
set.sem_num = 0;
set.sem_op = -1;
set.sem_flg = SEM_UNDO;
semop(id,&set,1);
}
void vBackKey(int id)
{
struct sembuf set;
set.sem_num = 0;
set.sem_op = 1;
set.sem_flg = SEM_UNDO;
semop(id,&set,1);
}
int main()
{
key_t key;
int semid;
union semun initsem;
initsem.val = 0;
key = ftok(".",1);
// 这个ftok函数参数1也可以换成‘z’的字符串
semid = semget(key,1,IPC_CREAT|0666);
// 1代表是只有一个信号量
semctl(semid,0,SETVAL,initsem);
//SETVAL设置信号量的值,设置为initsem
int pid = fork();
if(pid > 0){
pGetKey(semid);
//拿钥匙
printf("this is father\n");
vBackKey(semid);
//还钥匙
semctl(semid,0,IPC_RMID);
//关闭这个信号量
}
else if(pid == 0){
printf("this is child\n");
vBackKey(semid);
//还钥匙
}
else{
printf("fork error\n");
}
return 0;
}