关于信号量SEM_UNDO标志的问题

发布于 2022-10-15 09:22:22 字数 3609 浏览 17 评论 0

sem_lock() 和 sem_unlock() 都指定SEM_UNDO标志了
信号灯0:表示同一时间只有1个A资源可以使用
信号灯1:表示同一时间只有1个B资源可以使用

管理进程(进程1):
   // 初始有1个可用的A资源
   sem_unlock( 0 );

进程2(在进程1运行后创建):
   // 等待A资源可用
   sem_lock( 0 );
   ......
   
   // 释放B资源, 唤醒进程3
   sem_unlock( 1 );
   .....
   <D区域>
   .....

进程3:
   // 等待B资源
   sem_lock( 1 );
   ......
   
   // 释放A资源
   sem_unlock( 0 );
   ......

问题:当进程2在“d区域”异常退出(coredown)时,查看信号灯0的值, 变成"2"了?

针对进程2(工作进程)异常退出或主动kill掉,信号灯0的值又不想还原回去,不知各位大虾
有啥好的改进意见?

网上还搜到了一段话,针对信号量p操作,进程会保留调整值semadj, 在进程异常退出时会自动调整还原。
As we mentioned earlier, it is a problem if a process terminates
while it has resources allocated through a semaphore.
Whenever we specify the SEM_UNDO flag for a semaphore
operation and we allocate resources (a sem_op value less than 0),
the kernel remembers how many resources we allocated from
that particular semaphore (the absolute value of sem_op).
When the process terminates, either voluntarily or involuntarily,
the kernel checks whether the process has any outstanding semaphore
adjustments and, if so, applies the adjustment to the corresponding semaphore.

  1. int get_sem_val( int sem_id, int sem_slot )
  2. {
  3.         union semun arg;
  4.         return semctl( sem_id, sem_slot, GETVAL,arg );
  5. }
  6. int sem_lock( int sem_id, int sem_slot )
  7. {
  8.         union semun                arg;
  9.         struct sembuf         waittop;
  10.         waittop.sem_num = sem_slot;
  11.         waittop.sem_op = -1;
  12.         waittop.sem_flg = SEM_UNDO;
  13.        
  14.         if( semop( sem_id,&waittop,1 ) == -1 ) {
  15.                 arg.val = get_sem_val( sem_id, sem_slot ) - 1;
  16.                 return semctl( sem_id, sem_slot, SETVAL,arg );
  17.         }
  18.        
  19.         return 0;
  20. }
  21. int  sem_unlock(int sem_id, int sem_slot)
  22. {
  23.         union semun                arg;
  24.         struct sembuf         postop;
  25.         postop.sem_num = sem_slot;
  26.         postop.sem_op  = 1;
  27.         postop.sem_flg = SEM_UNDO;
  28.        
  29.         if( semop(sem_id,&postop,1 ) == -1 ) {
  30.                 arg.val = semctl( sem_id, sem_slot, GETVAL,0 )+1;
  31.                 semctl( sem_id, sem_slot, SETVAL, arg );
  32.         }
  33. }

复制代码

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文