【问题标题】:semop - is it possible to increment a semaphores (in a set of two), whilst the second semaphore is getting blockedsemop - 是否可以增加一个信号量(一组两个),而第二个信号量被阻塞
【发布时间】:2013-03-01 21:42:11
【问题描述】:

我有两个信号量应该以原子方式更改。

  union semun su;
  struct sembuf sb[2];
  int num = 2;

  semid = semget(num, 3, IPC_CREAT | IPC_EXCL | 0600);

  su.val = 1;
  semctl(semid, 0, SETVAL, su);
  su.val = 0;
  semctl(semid, 1, SETVAL, su);

  sb[0].sem_num = 0;
  sb[0].sem_op  = 1; // signal
  sb[0].sem_flg = 0;

  sb[1].sem_num = 1;
  sb[1].sem_op  = -1; //wait
  sb[1].sem_flg = 0;

  semop(semid, sb, 2)

如您所见,一个信号量应为signal(),另一个应为wait()

我在question 中读到,如果同时更改两个信号量,并且如果有一个信号量被阻塞,那么它不会真正改变另一个信号量 - 并且所有信号量都将进入休眠状态.

在我的实现中,对我来说非常重要的是:

  1. 两个信号量的两个操作都将以原子方式发生
  2. 如果第二个信号量将被阻止,则对第一个信号量没有影响。意味着第一个信号量将signal() 按原样进行,第二个信号量将wait()...

我无法从附加的问题中理解是否可以这样做,而且我不确定那里是否有答案......

所以想问问有没有可能

先谢谢了

【问题讨论】:

    标签: c linux semaphore


    【解决方案1】:

    我在这个问题中读到,如果两个信号量同时更改,并且如果有一个信号量被阻塞,那么它不会真正改变另一个信号量 - 并且所有信号量都将进入休眠状态。

    问题涉及的是信号量操作集是否以原子方式发生。答案正确地澄清了它是原子的。

    不要这样想

    "如果两个信号量同时改变"

    这样看

    "如果两个信号量都改变作为一个"

    我相信,你会理解原子性的概念。

    在上面的代码中很清楚地这样做了

    semop(semid, sb, 2)
    

    无论您的意图是什么,都会将信号量 sb[0] 和 ab[1] 作为单个操作执行。

    【讨论】:

    • 是的,我知道此操作将自动执行。问题是,因为属于该集合的一个信号量被阻塞,那么(据我所知)整个集合都将进入睡眠状态。所以第一个信号量的变化还不算数......
    【解决方案2】:

    首先,您的代码示例不正确,没有多大意义。应该是:

    sb[0].sem_num = 0;
    sb[0].sem_op = 1; // signal
    sb[0].sem_flg = 0;
    
    sb[1].sem_num = 1;
    sb[1].sem_op = -1; //wait
    sb[1].sem_flg = 0;
    
    semop(semid, sb, 2)
    

    您所描述的是可能的,这只是 2 个顺序操作:

    sb[0].sem_num = 0;
    sb[0].sem_op = 1; // signal
    sb[0].sem_flg = 0;
    semop(semid, sb, 1)
    
    sb[0].sem_num = 1;
    sb[0].sem_op = -1; // wait
    sb[0].sem_flg = 0;
    semop(semid, sb, 1)
    

    在 cmets 中讨论后,问题似乎可以改写为:我可以使 semop() 原子操作部分原子化吗?不,你不能,它是原子的。如果您不需要多个操作是原子的,请不要将它们放在一个 semop() 中。

    【讨论】:

    • 感谢sb[1].sem_num = 1; 的更正,但是使用您的解决方案-这两个操作不是原子执行的
    • 如果这两个操作将自动执行,那么第一个操作将等待第二个操作。如果第一个不需要等待第二个,为什么它需要与第二个原子?
    • 我希望操作以原子方式执行,我希望第一个信号量到signal(),第二个到wait() 原子地,而如果执行wait() 的人卡住了,它不会第一个信号量无关紧要,他的signal() 应该算数,这就是我想要创建的
    • 您要么希望它们以原子方式执行,要么不这样做。这里的原子意味着两个操作合二为一。如果第一个不依赖于第二个,则没有理由将它们都放在一个 semop() 调用中。或者请说明为什么它们需要按照您想要的方式进行。
    • 我希望它们以原子方式执行——在执行这些操作时不可能进行上下文切换或任何操作,不是因为它们相互依赖,而是因为这是它们必须执行的算法的一部分原子地保持算法的正确性。这是我的主题问题,如果可以的话
    猜你喜欢
    • 2011-06-30
    • 2020-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-01
    • 2021-06-14
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多