linux-IPC-Semaphore

信号量semaphore

信号量是一个计数器,用于为多个进程提供对共享数据对象的访问。常用的信号量形式为二元信号量(Binary semaphore)。它控制单个资源,初始值为1。但是,一般而言,信号量的初值可以是任意正数,该值表明有多少个共享资源单位可供共享应用。


数据结构

#include <sem.h>

struct ipc_perm
{
	__kernel_key_t	key;
	__kernel_uid_t	uid;
	__kernel_gid_t	gid;
	__kernel_uid_t	cuid;
	__kernel_gid_t	cgid;
	__kernel_mode_t	mode; 
	unsigned short	seq;
};

/* Obsolete, used only for backwards compatibility and libc5 compiles */
struct semid_ds {
	struct ipc_perm	sem_perm;		/* permissions .. see ipc.h */
	__kernel_time_t	sem_otime;		/* last semop time */
	__kernel_time_t	sem_ctime;		/* last change time */
	struct sem	*sem_base;		/* ptr to first semaphore in array */
	struct sem_queue *sem_pending;		/* pending operations to be processed */
	struct sem_queue **sem_pending_last;	/* last pending operation */
	struct sem_undo	*undo;			/* undo requests on this array */
	unsigned short	sem_nsems;		/* no. of semaphores in array */
};

操作函数

1.创建和引用信号量

#include <sem.h>

int semget(key_t key, int nsems, int flag);

2.控制信号量

#include <sem.h>

int semctl(int semid, int semunm, int cmd, ...arg);

/* arg for semctl system calls. */
union semun {
	int val;			/* value for SETVAL */
	struct semid_ds __user *buf;	/* buffer for IPC_STAT & IPC_SET */
	unsigned short __user *array;	/* array for GETALL & SETALL */
	struct seminfo __user *__buf;	/* buffer for IPC_INFO */
	void __user *__pad;
};

cmd参数:

IPC_STAT 对此集合去semid_ds结构,并存储在由arg.buf存储的结构中。

IPC_SET 按arg.buf指向的结构中的值,设置sem_perm.uid,sem_perm.gid和sem_perm.mode的值

IPC_RMID删除信号量的集合,该操作也是立即生效的。如果有其他进程正在使用这个信号量,则会返回EIDRM。

GETVAL返回semum的semval值

SETVAL设置semum的semval值

...

3.自动执行信号量集合上的操作数组

#include <sem.h>

int semop(int semid, struct sembuf semoparry[], size_t nops);

/* semop system calls takes an array of these. */
struct sembuf {
	unsigned short  sem_num;	/* semaphore index in array */
	short		sem_op;		/* semaphore operation */
	short		sem_flg;	/* operation flags */
};

参数semoparray是一个指针,指向一个由sembuf结构表示的信号量操作数组。

sem_op值:

1.如果为正,对应进程释放占用的资源数,sem_op值加到信号量的值上

2.如果为负,对应要获取该信号量控制的资源数,信号量减去sem_op值

3.如果为0,这表示调用进程希望等待该信号量的值变成0

 

如果信号量的值小于sem_op的绝对值,即资源不能满足要求。

1.若指定IPC_NOWAIT,则semop()返回EAGAIN

2.若未指定IPC_NOWAIT,信号量的semncnt+1,调用进程被挂起直到信号量满足要求,或者系统中删除了此信号量,或者接受到了一个信号,从信号处理程序返回EINTR。

 


参考书目:《APUE》

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值