linux进程间信号量的等待投递

linux进程间信号量的等待投递,第1张

每个信号量都具有一个非负的值,且信号量支持等待和投递操作。系统调用 semop 实现了这两个操作。它的第一个参数是信号量的标识符,第二个参数是一个包含 struct sembuf 类型元素的数组;这些元素指明了您希望执行的操作。第三个参数是这个数组的长度。结构体sembuf中包含如下字段:

sem_num将要执行操作的信号量组中包含的信号量数量。 sem_op是一个指定了操作类型的整数。 如果sem_op是一个正整数,则这个值会立刻被加到信号量的值上。 [BR]如果 sem_op 为负,则将从信号量值中减去它的绝对值。如果这将使信号量的值小于零,则这个操作会导致进程阻塞,直到信号量的值至少等于操作值的绝对值(由其它进程增加它的值)。 [BR]如果 sem_op 为0,这个操作会导致进程阻塞,直到信号量的值为零才恢复。 sem_flg 是一个符号位。指定 IPC_NOWAIT 以防止操作阻塞;如果该操作本应阻塞,则semop调用会失败。如果为sem_flg指定SEM_UNDO,Linux会在进程退出的时候自动撤销该次操作。 代码 5.4 展示了二元信号量的等待和投递操作。

代码 5.4 (sem_pv.c)二元信号量等待和投递操作

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/sem.h>

/* 等待一个二元信号量。阻塞直到信号量的值为正,然后将其减1 */

int binary_semaphore_wait (int semid)

{

struct sembuf operations[1]

/* 使用(且仅使用)第一个信号量 */

operations[0].sem_num = 0

/* 减一。 */

operations[0].sem_op = -1

/* 允许撤销操作 */

operations[0].sem_flg = SEM_UNDO

return semop (semid, operations, 1)

}

/* 对一个二元信号量执行投递操作:将其值加一。 这个操作会立即返回。*/

int binary_semaphore_post (int semid)

{

struct sembuf operations[1]

/* 使用(且仅使用)第一个信号量 */

operations[0].sem_num = 0

/* 加一 */

operations[0].sem_op = 1

/* 允许撤销操作 */

operations[0].sem_flg = SEM_UNDO

return semop (semid, operations, 1)

}

指定 SEM_UNDO 标志解决当出现一个进程仍然持有信号量资源时被终止这种特殊情况时可能出现的资源泄漏问题。当一个进程被有意识或者无意识地结束的时候,信号量的值会被调整到“撤销”了所有该进程执行过的操作后的状态。例如,如果一个进程在被杀死之前减小了一个信号量的值,则该信号量的值会增长。

他把答案删除了,所以我也得改下了。

--------------------------

semop() 这是个信号函数。

系统调用:semop()

调用原型:int semop(int semid,struct sembuf*sops,unsign ednsops)

返回值:0,如果成功。-1,如果失败:errno=E2BIG(nsops大于最大的ops数目)

EACCESS(权限不够)

EAGAIN(使用了IPC_NOWAIT,但操作不能继续进行)

EFAULT(sops指向的地址无效)

EIDRM(信号量集已经删除)

EINTR(当睡眠时接收到其他信号)

EINVAL(信号量集不存在,或者semid无效)

ENOMEM(使用了SEM_UNDO,但无足够的内存创建所需的数据结构)

ERANGE(信号量值超出范围)

第一个参数是关键字值。第二个参数是指向将要操作的数组的指针。第三个参数是数组中的操作的个数。参数sops指向由sembuf组成的数组。此数组是在linux/sem.h中定义的:

/*semop systemcall takes an array of these*/

structsembuf{

ushortsem_num/*semaphore index in array*/

shortsem_op/*semaphore operation*/

shortsem_flg/*operation flags*/

sem_num将要处理的信号量的个数。

sem_op要执行的操作。

sem_flg操作标志。

如果sem_op是负数,那么信号量将减去它的值。这和信号量控制的资源有关。如果没有使用IPC_NOWAIT,那么调用进程将进入睡眠状态,直到信号量控制的资源可以使用为止。如果sem_op是正数,则信号量加上它的值。这也就是进程释放信号量控制的资源。最后,如果sem_op是0,那么调用进程将调用sleep(),直到信号量的值为0。这在一个进程等待完全空闲的资源时使用。

--------------------------

还比如: Semget(),semctl() 等。如有需要解释这些函数,你等加加分哦,我就一一讲解。

这是sys/sem.h文件的内容

/* @(#) sem.h 1.3 1/27/86 17:47:09 */

/*ident "@(#)cfront:incl/sys/sem.h 1.3"*/

/*

** IPC Semaphore Facility.

*/

/*

** Implementation Constants.

*/

#define PSEMN (PZERO + 3) /* sleep priority waiting for greater value */

#define PSEMZ (PZERO + 2) /* sleep priority waiting for zero */

/*

** Permission Definitions.

*/

#define SEM_A 0200 /* alter permission */

#define SEM_R 0400 /* read permission */

/*

** Semaphore Operation Flags.

*/

#define SEM_UNDO 010000 /* set up adjust on exit entry */

/*

** Semctl Command Definitions.

*/

#define GETNCNT 3 /* get semncnt */

#define GETPID 4 /* get sempid */

#define GETVAL 5 /* get semval */

#define GETALL 6 /* get all semval's */

#define GETZCNT 7 /* get semzcnt */

#define SETVAL 8 /* set semval */

#define SETALL 9 /* set all semval's */

/*

** Structure Definitions.

*/

/*

** There is one semaphore id data structure for each set of semaphores

** in the system.

*/

struct semid_ds {

struct ipc_perm sem_perm/* operation permission struct */

struct sem *sem_base/* ptr to first semaphore in set */

ushort sem_nsems/* # of semaphores in set */

time_t sem_otime/* last semop time */

time_t sem_ctime/* last change time */

}

/*

** There is one semaphore structure for each semaphore in the system.

*/

struct sem {

ushort semval /* semaphore text map address */

short sempid /* pid of last operation */

ushort semncnt/* # awaiting semval >cval */

ushort semzcnt/* # awaiting semval = 0 */

}

/*

** There is one undo structure per process in the system.

*/

struct sem_undo {

struct sem_undo *un_np/* ptr to next active undo structure */

short un_cnt/* # of active entries */

struct undo {

short un_aoe/* adjust on exit values */

short un_num/* semaphore # */

int un_id/* semid */

} un_ent[1]/* undo entries (one minimum) */

}

/*

** semaphore information structure

*/

struct seminfo {

int semmap, /* # of entries in semaphore map */

semmni, /* # of semaphore identifiers */

semmns, /* # of semaphores in system */

semmnu, /* # of undo structures in system */

semmsl, /* max # of semaphores per id */

semopm, /* max # of operations per semop call */

semume, /* max # of undo entries per process */

semusz, /* size in bytes of undo structure */

semvmx, /* semaphore maximum value */

semaem /* adjust on exit max value */

}

/*

** User semaphore template for semop system calls.

*/

struct sembuf {

ushort sem_num/* semaphore # */

short sem_op /* semaphore operation */

short sem_flg/* operation flags */

}

//

union semum {

int val

struct semid_ds *bf

ushort *array

} arg

extern int semctl (int, int, int, semum),

semget (key_t, int, int),

semop (int, sembuf**, int)


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/89659.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-03-06
下一篇2023-03-06

发表评论

登录后才能评论

评论列表(0条)

    保存