Linux高级进程间通信:信号量

父进程产生三个子进程,每一个都使用p()和v()来阻止其他进程在同一时刻执行一段关键区域。

 

 

pv.h:

/*semaphore exapmle header file */
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<errno.h>

#define SEMPERM   0600
#define  FALSE     0
#define   TRUE    1
/* use typedef so we can do like this:{semun mymun;} */
/*to define a union */
typedef union _semun{    
	int val;    
	struct semid_ds *buf;   
	ushort *array;
	}semun;
	


 

initsem.c:

#include "pv.h"
/*initsem----semaphore initialization */
int initsem(key_t semkey)
{  
  int status=0,semid;    
  if((semid=semget(semkey,1,SEMPERM|IPC_CREAT|IPC_EXCL))==-1)    
	{       
	  if(errno==EEXIST)//if exist,get the semkey      
	   	{            
		   semid=semget(semkey,1,0);      
	   	}  
	} 
	/*if create succeeded*/  
   else 
	{      
		semun arg;//define a semun union    
		arg.val=1;//1 sem    
		status=semctl(semid,0,SETVAL,arg);//the index begin from 0表示只有一个信号量  
	}   

	if(semid==-1||status==-1)   
		{      
			perror("initsem failed");     
		    return (-1);  
		}   

	/*all OK */  
	return (semid);
}


 

 

 

p.c:

 

/*p.c---semaphore p operation--wait*/
#include "pv.h"
int p(int semid)
{    
	struct sembuf p_buf;   
	p_buf.sem_num=0;	//include a sem   
	p_buf.sem_op=-1;    //p,wait  
	p_buf.sem_flg=SEM_UNDO;//undo表示进程退出时抵消对信号量的影响,因此所有进程退出后信号值的初值还是一样的    
	if(semop(semid,&p_buf,1)==-1)//1 means??only have a struct?   
	{   
		perror("P(semid) failed");      
		exit (1);  
	}   
	return (0);
}


 

 

v.c:

 

/*v.c----semaphore v operation--signal */
#include "pv.h"

int v(int semid)
{   
	struct sembuf v_buf;   
	v_buf.sem_num=0;//1 sem   
	v_buf.sem_op=1;//v signal  
	v_buf.sem_flg=SEM_UNDO;//undo  
	if(semop(semid,&v_buf,1)==-1)   
	{      
		perror("v(semid)failed");   
		exit (1);  
		}   
	return (0);
}


 

 

testsem.c:

 

/* testsem.c----test semaphore routines */
#include "pv.h"
#include<stdio.h>

void handlesem(key_t skey);

int main(void)
{   
	key_t semkey=0x200;    
	int i;  
	for(i=0;i<3;i++) //create three process  
	{       
		if(fork()==0)//child    
	    {          
			handlesem(semkey);   
		}   
	}   
	return 0;
}

void handlesem(key_t skey)
{   
	int semid;  
	pid_t pid=getpid();//get pid 
	if((semid=initsem(skey))<0)//initialize sem   
	{      
	 exit (1);  
	}   
	printf("/nprocess %d before critical section /n",pid);    
	p(semid);  
	printf("process %d in critical section /n",pid);  
	/* do something when wait succeeded  
	*     *     *     *     *     */  
	sleep(5);   
	printf("process %d leaving critical section/n",pid);  
	v(semid);
	printf("process %d exiting /n",pid); 
	exit (0);
}


 

 

运行结果:
jiang@jiang-linux:~/unixprog/2011324$ gcc initsem.c p.c v.c testsem.c -o testsem.o;./testsem.o
process 2731 before critical section
process 2731 in critical section

process 2732 before critical section

process 2733 before critical section
process 2731 leaving critical section
process 2731 exiting
process 2732 in critical section
process 2732 leaving critical section
process 2732 exiting
process 2733 in critical section
process 2733 leaving critical section
process 2733 exiting

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值