信号量 ——什么是信号量

信号量

信号量(semaphore)与已经介绍过的 IPC 结构不同,它是一个计数器。信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信数据。

1、特点
信号量用于进程间同步,若要在进程间传递数据需要结合共享内存。

信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作。

每次对信号量的 PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数。

支持信号量组

函数原型

1 #include <sys/sem.h>

2 // 创建或获取一个信号量组:若成功返回信号量集ID,失败返回-1

3 int semget(key_t key, int num_sems, int sem_flags);

4 // 对信号量组进行操作,改变信号量的值:成功返回0,失败返回-1

5 int semop(int semid, struct sembuf semoparray[], size_t numops);  

6 // 控制信号量的相关信息

7 int semctl(int semid, int sem_num, int cmd, ...);
#include
#include 
#include 
#include 
#include 
#include

//int semop(int semid, struct sembuf *sops, size_t nsops);
//int semget(key_t key, int nse:ms, int semflg);
//int semctl(int semid, int semnum, int cmd, ...);

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;

	if(semop(id,&set,1)==-1){
		perror("semop");
		exit(EXIT_FAILURE);
	}   
}

void vPutBackkey(int id)
{
	struct sembuf set;
	set.sem_num=0;
	set.sem_op=1;
	set.sem_flg=SEM_UNDO;

	if(semop(id,&set,1)==-1){
		perror("semop");
		exit(EXIT_FAILURE);
	}   
}



int main(int argc,char **argv)
{
	key_t key;

	key=ftok(".",1);
	if(key==-1){
		printf("key=%x\n",key);
	}

	int semid=semget(key,1,IPC_CREAT|0666);
	if(semid==-1){
		printf("semget failed\n");
	}

	union semun initsem;
	initsem.val=0;
	int ret=semctl(semid,0,SETVAL,initsem);
	if(ret==-1){
		printf("semctl success\n");
	}

	pid_t pid;

	pid=fork();

	if(pid>0){
		pGetkey(semid);     
		printf("this is father\n");
		vPutBackkey(semid);
		semctl(semid,1,IPC_RMID);
	}else if(pid==0){

		printf("this is child\n");
		vPutBackkey(semid);
	}else{

		printf("failed\n");	   

	}
}

你可能感兴趣的:(linux进程间通信,linux,c语言)