信号量

信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端。确认这些信号量VI引用的是初始创建的信号量。

 

 

 

Semget

功能描述

  函数原型:int semget(key_t key,int nsems,int semflg);

  功能描述

  获取与某个键关联的信号量集标识。信号量集被建立的情况有两

  1.如果IPC_PRIVATE

  2.或者不是IPC_PRIVATE,并且对应的信号量集不存在,同时标志中指定IPC_CREAT

  当semget建一个信号量,他的相semid_ds构被初始化。ipc_perm中各个量被

  

  sem_nsemsnsems所示的

  sem_otime0

  sem_ctime当前时间

用法

  #include <sys/types.h>

  #include <sys/ipc.h>

  #include <sys/sem.h>

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

  key:所建或打信号量集的键值

  nsems建的信号量集中的信号量的个数,参数只在建信号量集有效。

  flag用函数的操作型,也可用于置信号量集的访问权限,两者通or表示

  返回值说明:

  如果成功,返回信号量集的IPC标识符。

  如果失返回-1errno定成以下的某个

  EACCES:没有访问该信号量集的

  EEXIST:信号量集已存在,无法

  EINVAL:参数nsems小于0或者大于信号量集的限制;或者是key关联的信号量集已存在,并且nsems

  大于信号量集的信号量数

  ENOENT:信号量集不存在,同没有使用IPC_CREAT

  ENOMEM :没有足的内存建新的信号量集

   ENOSPC:超出系统限制

 

semctl

semctl()系统调用:semctl();

  原型:int semctl(int semid,int semnum,int cmd,union semunarg);

  返回值:如果成功,则为一个正数。

  如果失败,则为-1errno=EACCESS(权限不够)

  EFAULT(arg指向的地址无效)

  EIDRM(信号量集已经删除)

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

  EPERM(EUID没有cmd)

  ERANGE(信号量超出范)

  系统调semctl用来行在信号量集上的控制操作。和在消息列中的系统调msgctl是十分相似的。但两个系统调用的参数略有不同。因信号量一般是作一个信号量集使用的,而不是一个独的信号量。所以在信号量集的操作中,不但要知道IPC关键,也要知道信号量集中的具体的信号量。两个系统调用都使用了参数cmd,它用来指出要操作的具体命令。两个系统调用中的最后一个参数也不一。在系统调msgctl中,最后一个参数是指向内核中使用的数据构的指。我使用此数据构来取得有消息列的一些信息,以及置或者改变队列的存取限和使用者。但在信号量中支持外的可的命令,这样就要求有一个更为复杂的数据构。

  系统调semctl()的第一个参数是关键。第二个参数是信号量数目。

  参数cmd中可以使用的命令如下:

  ·IPC_STAT取一个信号量集的数据semid_ds,并将其存semun中的buf参数中。

  ·IPC_SET置信号量集的数据semid_ds中的元素ipc_perm,其取自semun中的buf参数。

  ·IPC_RMID将信号量集从内存中除。

  ·GETALL用于取信号量集中的所有信号量的

  ·GETNCNT返回正在等待资源程数目。

  ·GETPID返回最后一个semop操作的程的PID

  ·GETVAL返回信号量集中的一个个的信号量的

  ·GETZCNT返回在等待完全空源的程数目。

  ·SETALL置信号量集中的所有的信号量的

  ·SETVAL置信号量集中的一个独的信号量的

  参数arg代表一个semun例。semun是在linux/sem.h中定的:

  /*arg for semctl systemcalls.*/

  unionsemun{

  intval;/*value for SETVAL*/

  structsemid_ds*buf;/*buffer for IPC_STAT&IPC_SET*/

  ushort*array;/*array for GETALL&SETALL*/

  structseminfo*__buf;/*buffer for IPC_INFO*/

  void*__pad;

  val当执行SETVAL命令时使用。bufIPC_STAT/IPC_SET命令中使用。代表了内核中使用的信号量的数据结构。array在使用GETALL/SETALL命令时使用的指针。

  下面的程序返回信号量的值。当使用GETVAL命令时,调用中的最后一个参数被忽略:

  intget_sem_val(intsid,intsemnum)

  {

  return(semctl(sid,semnum,GETVAL,0));

  }

  下面是一个实际应用的例子:

  #defineMAX_PRINTERS5

  printer_usage()

  {

  int x;

  for(x=0;x<MAX_PRINTERS;x++)

  printf("Printer%d:%d/n/r",x,get_sem_val(sid,x));

  }

  下面的程序可以用来初始化一个新的信号量

  void init_semaphore(int sid,int semnum,int initval)

  {

  union semunsemopts;

  semopts.val=initval;

  semctl(sid,semnum,SETVAL,semopts);

  }

  注意系统调semctl中的最后一个参数是一个型的副本,而不是一个指向型的指

 

semop

semop统调

功能描述:

  操作一个或一信号。

用法:

  #include <sys/types.h>

  #include <sys/ipc.h>

  #include <sys/sem.h>

  int semop(int semid, struct sembuf *sops, unsigned nsops);

  int  semtimedop(int  semid, struct sembuf *sops, unsigned nsops, struct timespec *timeout);

参数:

  semid:信号集的识别码,可通semget取。

  sops:指向存信号操作构的数,信号操作构的原型如下

  struct sembuf

  {

  unsigned short sem_num;  /* semaphore number */

  short          sem_op;   /* semaphore operation */

  short          sem_flg;  /* operation flags */

  };

  这三个字段的意义分别为:

  sem_num:操作信号在信号集中的编号,第一个信号的编号是0

  sem_op:如果其值为正数,该值会加到有的信号内含中。通常用于放所控源的使用;如果sem_op值为负数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号大于或等于sem_op绝对值。通常用于源的使用;如果sem_op值为0操作将暂时阻塞,直到信号的值变为0

  sem_flg:信号操作志,可能的选择有两

  IPC_NOWAIT //信号的操作不能semop()不会阻塞,并立即返回,同时设错误信息。

  IPC_UNDO //程序(正常或不正常),保信号会被重设为semop()用前的这样做的目的在于避免程序在异常情况下未将定的源解,造成该资源永远锁定。

  nsops:信号操作构的数量,恒大于或等于1

  timeout:当semtimedop()用致使入睡眠,睡眠时间不能超本参数指定的。如果睡眠超semtimedop()将失返回,并错误值为EAGAIN。如果本参数的值为NULLsemtimedop()将永睡眠等待。

返回明:

  成功,两个系统调用都返回0。失返回-1errno设为以下的某个

  E2BIG:一次信号的操作数超出系的限制

  EACCES程没有求的操作,并且不具有CAP_IPC_OWNER

  EAGAIN:信号操作暂时不能足,需要重

  EFAULTsopstimeout指向的空不可访问

  EFBIGsem_num指定的无效

  EIDRM:信号集已被移除

  EINTR:系统调用阻塞,被信号中断

  EINVAL:参数无效

  ENOMEM:内存不足

  ERANGE:信号所允许的值越界

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值