信号量

信号量的本质是描述临界资源数目的信号量,是一种数据操作锁,对信号量进行的增减操作均为原子的;
为什莫使用信号量:为了防止多个进程同时访问一个共享资源而引起的一系列问题;让一个临界区同一时间只能有一个线程访问它;
工作原理:举例说明,若两个进程共享信号量sv,一旦其中一个进程执行P操作,使得sv减1,它将得到信号量,并且进入临界区,若另一进程此时再执行p操作将会被挂起,直到第一个进程离开临界区执行v操作;
//comm.h
#include<sys/ipc.h>
#include<stdio.h>
#include<sys/sem.h>
#include<sys/types.h>
#include <stdlib.h>

#define PATHNAME "."
#define PROJ_ID 0x6666

union semun {
     int  val;   
	 struct semid_ds *buf;     
     unsigned short  *array;   
     struct seminfo  *__buf;   
 };




int creatSem();
int initSem();
int getSem();
int destorySem();
int P();
int V();

//comm.c

#include"comm.h"

int commSem(int num,int flags)
{
	int semid;
	key_t _key=ftok(PATHNAME,PROJ_ID);
	if(_key<0)
	{
		perror("ftok");
		return -1;
	}
	if((semid=semget(_key,num,flags))<0)
	{
		perror("semget");
		return -2;
	}
	return semid;
}

int creatSem(int num)
{
	return commSem(num,IPC_CREAT|IPC_EXCL|0666);
}

int initSem(int semid,int semnum,int value)
{
	union semun un;
	un.val=value;
	if(semctl(semid,semnum,SETVAL,un)<0)	
	{
		perror("init _semctl");
		return -3;
	}
	return 0;
}

int getSem(int num)
{
	return commSem(num,IPC_CREAT);
}

	int destorySem(int semid)
	{
		if(semctl(semid,0,IPC_RMID)<0)
		{
			perror("destory _semid");
			return -3;
		}
		return 0;	
	}

int operatSem(int semid,int op)
{
	struct sembuf buf;
	buf.sem_num=0;
	buf.sem_op=op;
	buf.sem_flg=0;
   int oop=semop(semid,&buf,1);
   if(oop<0)
   {
	   perror("semop");
	   return -4;
   }
}

int P(int semid)
{
	operatSem(semid,-1);
}


int V(int semid)
{
	operatSem(semid,1);
}

//test.c
#include"comm.h"

int main()
{
	int semid=creatSem(1);
	initSem(semid,0,1);
	pid_t id=fork();
	 if(id<0)
	 {
		 perror("fork()");
		 return 5;
	 }
	 else if(id==0)
	 {//child
	    int semid=getSem(1);
		P(semid);
		int count=0;
		while(count++<5)
		{
		//	sleep(1);
			printf("A\n");
			sleep(1);
			printf("A\n");
		}
		V(semid);
	//	exit(0);
	 }
	 else
	 {//father
		 P(semid);
		 int count=0;
		 while(count++<5)
		 {
			 sleep(1);
			 printf("B\n");
			 sleep(1);
			 printf("B\n");
		 }
		 V(semid);
		 waitpid(id,NULL,0);
	 }
	 destorySem(semid);



	 return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值