2013-02-20 99 views
3

所以,問題是:我正在爲我的大學項目編寫一個「聊天模擬器」。沒有深入細節,客戶端可以多次運行,並且所有實例都使用由信號量(除其他外)保護的同一段共享內存。誰初始化信號燈?

客戶在未知的時間進入和退出系統。當第一個客戶端進入系統時,它應該創建一個信號量,使用共享內存並釋放。但是,如果有其他客戶端進入系統,則必須在獲取共享內存訪問權之前等待信號量。

現在,我覺得我錯過了一些明顯的東西 - 我該如何初始化信號量?如果我使用semget(42, 1, IPC_CREAT),那麼產生的信號量很可能是0 - 但我不能提高它來初始化它,因爲0可能意味着臨界區已經有一個過程。換句話說,我不知道我是否剛剛創建了默認值爲0的信號量,或者是否有信號量在等待信號量。

僞代碼:

if(semaphore_not_exists(42)) 
{ 
    create_sem; 
    raise_sem; 
} 
else 
{ 
    get_sem_handle; 
} 
wait_on_sem; 
critical_section; 
release_sem; 

那麼,我該如何確保信號量尚未被另一個進程創建的,所以它的安全初始化呢?如果我使用IPC_EXCL,請求將失敗,但我不知道接下來應該做什麼。

+1

我認爲信號量的所有用戶需要獲得它已經初始化。否則,信號量本身的初始化會受到競爭條件的影響。 – UmNyobe 2013-02-20 16:09:49

+0

由於某些原因,您是否需要使用SysV信號量? – zwol 2013-02-20 16:23:35

+0

這就是我在課程期間教過的內容,但我猜想替代方法不會有問題。爲什麼,它們是過時的還是什麼? – 2013-02-20 16:25:44

回答

0

我認爲信號量的所有用戶都需要獲取已經初始化的信號量。否則,信號量本身的初始化會受到競爭條件的影響。 你可以有一個守護進程在系統引導初始化信號,並採取

create_sem; 
raise_sem; 

照顧,同時客戶只需要執行

get_sem_handle; 
+0

那麼,唯一的選擇是有一個完全獨立的進程來初始化信號量?我必須在啓動客戶端之前每次運行它(因爲我無法真正在uni計算機上修改init腳本)?嗯,希望有更優雅的東西... – 2013-02-20 16:21:03

2

你可以做類似如下:

  1. 呼叫semget(key, nsems, IPC_CREAT | IPC_EXCL)。如果成功,現在你已經創建了一個新的信號集,你那麼應通過semctl()
  2. 設置如果以前semget()失敗了,再打電話semget(),沒有IPC_EXCL標誌。

我還建議使用lockfile(通過flock()或類似的)來確保信號集在初始化之前不被使用。