Linux XSI IPC 之信号量

关于信号量的定义和系统调用,可以查看这篇博文:点击打开链接

其中,注意一点就是:在编译信号量程序时,semctl 函数,其中一个参数是union semun 联合体。但是在编译时,union semun _semval; 这段声明联合体的代码却报错:storage size of '_semval'  isn't known. 查看semctl手册,在Notes中可以看到这么一段:In some earlier versions og glibc,the semun union was defined in <sys/sem.h>,but POSIX.1-2001 requires that the caller define this union.On versions of glibc where this union is not defined, the macro _SEM_SEMUN_UNDEFINED is defined in <sys/sem.h>。因此,该问题的解决方案就是测试宏,如果定义了该宏,则自己在程序中定义union semun 结构体。

下面是自己写的示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

void my_err(char *);
int semphore_p(int);
int semphore_v(int);

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

int main(void)
{
	printf("start\n");
	key_t key;
	int semid;
	pid_t pid;
	if((key=ftok("/tmp/test_sem.c",0))==-1)			
		my_err("ftok error");
	if((semid=semget(key,1,IPC_CREAT))==-1)
		my_err("semget error");
	union semun semun_val;
	semun_val.val=1;	
	if(semctl(semid,0,SETVAL,semun_val)==-1)	
		my_err("semctl set error");
	if((pid=fork())==-1)
		my_err("fork error");
	else if(pid==0)
	{
		sleep(1);
		if(semphore_p(semid)==-1)
			my_err("child semphore_p error");
		printf("child\n");
		if(semphore_v(semid)==-1)
			perror("semor child error.....");
		printf("child will exit\n");
		exit(0);
	}
	else 
	{
		if(semphore_p(semid)==-1)
			my_err("parent semphore_p error");
		printf("parent\n");
		sleep(3);
		if(semphore_v(semid)==-1)
			my_err("parent semphore_v error");
	}
	printf("parent will sleep,after wake,sem will be removed\n");
	sleep(2);
	if(semctl(semid,0,IPC_RMID,NULL)==-1)
		my_err("semctl rm error");
	printf("end\n");
	exit(0);
}
//P操作,申请一个资源单位
int semphore_p(int semid)
{
	struct sembuf _sembuf;
	_sembuf.sem_num=0;
	_sembuf.sem_op=-1;
	_sembuf.sem_flg=SEM_UNDO;
	if(semop(semid,&_sembuf,1)==-1)
		return -1;
	return 0;
}
//V操作,释放一个资源单位
int semphore_v(int semid)
{
	struct sembuf _sembuf;
	_sembuf.sem_num=0;
	_sembuf.sem_op=1;
	_sembuf.sem_flg=IPC_NOWAIT;
	if(semop(semid,&_sembuf,1)==-1)
		return -1;
	return 0;
}

void my_err(char *str)
{
	printf("Line:%d,",__LINE__);
	perror(str);
	exit(1);
}

   
   
  
  

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值