2013-03-01 54 views
1

我有兩個信號應該改變原子。semop - 是否有可能增加信號量(在一組兩個),而第二個信號被阻止

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() ...

我無法從所連接的問題,瞭解是否有可能做的,我不知道有回答有...

所以我想問問,如果有可能

感謝提前

回答

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()原子操作部分原子化?不,你不能,它是原子的。如果不需要多個操作是原子操作,請不要將它們放在一個semop()中。

+0

感謝SB的'校正[1] .sem_num = 1;',但隨着你的溶液 - 這兩個操作不原子 – hudac 2013-03-02 00:13:34

+0

執行如果兩個操作將原子執行,則第一操作將等待第二。如果第一個人不需要等待第二個,爲什麼需要第二個原子呢? – Slava 2013-03-02 20:39:24

+0

我想要的操作原子執行, 我想第一個信號,以'信號()',而第二到'wait()的'原子,而如果誰做了一個'等待()'卡住,這不是」對於第一旗語牛逼的事,他的'信號()'應該算,這就是我想要的創建 – hudac 2013-03-02 20:52:32

1

我在這個問題看,如果兩個信號燈的一次改變,如果有一個信號量被阻塞,那麼它並沒有真正改變等 - 所有的一套打算睡覺。

問題的關鍵是信號操作集是否是自動發生的。答案正確地將其解釋爲原子。

而是這樣想的

看它這樣「如果兩個信號燈的一次改變」

「如果兩個信號燈的是改變作爲一個

我相信,你會欣賞原子性的概念。

所以在上面的代碼清楚這樣做

semop(semid, sb, 2) 

將同時進行旗語SB [0]和操作AB [1] 作爲一個單一的操作,無論你的意圖是什麼。

+0

是的,我明白,這一行動將原子進行。問題是,因爲屬於這個集合的一個信號量被阻塞了,那麼(據我所知)整個集合將會進入睡眠狀態。所以第一個信號量的變化還不算真正的數量...... – hudac 2013-03-02 00:15:43

相關問題