1

アトミックに変更する必要がある 2 つのセマフォがあります。

  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()です。

この質問で、両方のセマフォが一度に変更された場合、ブロックされたセマフォが 1 つある場合、もう一方のセマフォは実際には変更されず、すべてのセットがスリープ状態になることを読みました。

私の実装では、次のことが非常に重要です。

  1. 2 つのセマフォの両方の操作がアトミックに行われます。
  2. 2 番目のセマフォがブロックされても、最初のセマフォには関係ありません。最初のセマフォはsignal()想定どおりに動作し、2 番目のセマフォはwait()...

添付の質問からそれが可能かどうか理解できず、そこに答えがあるかどうかわかりません...

それで、可能かどうか尋ねたかったのです

よろしくお願いします

4

2 に答える 2

1

この質問で、両方のセマフォが一度に変更された場合、ブロックされたセマフォが 1 つある場合、もう一方のセマフォは実際には変更されず、すべてのセットがスリープ状態になることを読みました。

問題は、一連のセマフォ操作がアトミックに発生するかどうかです。答えは、それがアトミックであることを正しく明確にしました。

このように考えるのではなく

「両方のセマフォが一度に変更された場合」

こう見て

"両方のセマフォが1 つに変更された場合"

そうすれば、アトミック性の概念を理解していただけると思います。

上記のコードでこれを行っていることは明らかです

semop(semid, sb, 2)

意図に関係なく、セマフォ sb[0] と ab[1] の両方の操作を単一の操作として実行します。

于 2013-03-01T21:59:16.663 に答える
0

まず第一に、あなたのコード サンプルは正しくなく、あまり意味がありません。代わりに次のようにする必要があります。

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)

コメントで議論した後、質問は次のように言い換えることができるようです: semop() アトミック操作を部分的にアトミックにできますか? いいえ、できません。アトミックです。複数の操作をアトミックにする必要がない場合は、それらを 1 つの semop() に入れないでください。

于 2013-03-01T21:55:24.737 に答える