首页 > 其他 > 详细

信号量

时间:2020-09-14 12:43:05      阅读:51      评论:0      收藏:0      [点我收藏+]

Linux内核信号量集用结构体semid_ds结构体表示,semid_ds的结构体定义如下:

/* Data structure describing a set of semaphores.  */
struct semid_ds
{
  struct ipc_perm sem_perm;        /* operation permission struct */
  __time_t sem_otime;            /* last semop() time */
  __syscall_ulong_t __glibc_reserved1;
  __time_t sem_ctime;            /* last time changed by semctl() */
  __syscall_ulong_t __glibc_reserved2;
  __syscall_ulong_t sem_nsems;        /* number of semaphores in set */
  __syscall_ulong_t __glibc_reserved3;
  __syscall_ulong_t __glibc_reserved4;
};

每个信号量则描述为:

struct sem{
       int    semval ;
       int    sempid ;     
       int    semcnt ;
       int    semzcnt;
};  

信号量的基本操作包括创建信号量、信号量的值操作、获取或设置信号量属性,对应的相关函数的分别是semget、semop、semctl。

1.创建信号量集

semget函数用于创建信号量,如果参数key指定的信号量集已经存在,则就返回该信号量集。

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semget(key_t key, int nsems, int flag);

key:一个整数类型的键值,用来命名某个特定的信号量集。

nsems:指定打开或者新创建的信号量集包含的信号量数目。

falg:9个位的权限标志。

返回值:成功返回信号量集描述字,否则返回-1。

2.信号量值操作

信号量本质上是一个计数器,进程可以使用函数semop来增加或者减少信号量值,以表示释放或者申请共享资源。

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
int semop(int sem_id, struct sembuf * sops, unsigned int nsops);

sem_id:semget函数返回的信号量集描述字。

nsops:本次操作的信号量数目,也是sops指向的数组的大小。

sops:指向一个类型为sembuf的结构体数组。

sembuf结构体:

/* Structure used for argument to `semop‘ to describe operations.  */
struct sembuf
{
  unsigned short int sem_num;    /* semaphore number */
  short int sem_op;        /* semaphore operation */
  short int sem_flg;        /* operation flag */
};

如果sem_op为负数,就从信号量值中减去sem_op的绝对值,表示进程获取资源;如果sem_op为正数,就把它加到信号量上,表示归还资源;如果sem_op为0,则调用进程睡眠,直到信号量值为0。sem_flag一般设置为0。

3.获取或者设置信号量属性

系统中的每个信号量集都对应一个struct sem_ds结构体,该结构体记录信号量集的各种信息,存放于内核空间。为了设置、获取信号量集的各种信息及属性,在用户空间中有一个联合体union semnu与之对应。

union semun {
    int              val;    /* Value for SETVAL */
    struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
    unsigned short  *array;  /* Array for GETALL, SETALL */
    struct seminfo  *__buf;  /* Buffer for IPC_INF    (Linux-specific) */
};

信号量属性操作的函数原型:

#include <linux/sem.h>
int semctl(int semid, int semnum, int cmd, union semun arg);

semid:信号量集描述字。

semnum:待操作的信号量在信号集semid中的索引。

cmd:指定具体的操作类型,常见的操作有:

  SETVAL:设置semnum所代表信号量的值为arg.val。

  SETALL:通过arg.val更新所有信号量的值。

  IPC_RMID:从内核主存中删除信号量集。

    

 

信号量

原文:https://www.cnblogs.com/iuyy/p/13665796.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!