2009-09-21 126 views
2

我假設一旦進程創建了一個信號量,任何進程/用戶都可以訪問它。在Semaphore上設置訪問權限?

是否有可能對特定信號量設置訪問限制,以便僅可由某些進程/用戶訪問,或者只有某些進程才能釋放信號量。
如果我們使所有進程都可以訪問信號量,我會看到一些問題。例如:虛擬進程可以讀取信號量並釋放鎖,以便向真正等待信號鎖的實際進程發出虛假信號。

所有這些問題產生的,因爲我變得很怪異輸出與下面的代碼片段:

use Win32::Semaphore; 

$sem = Win32::Semaphore->new(0, 1,"reliance2692") 
    or print "Can't create semaphore\n"; 

$sem = Win32::Semaphore->open("reliance2692") 
    or print "Can't open semaphore\n"; 

print "Semaphore:" . $sem . "\n"; 

通過運行上面的程序,我得到下面的輸出

 
Can't create semaphore 
Can't open semaphore 

輸出表明它未能創建信號量,甚至未能打開信號量。如果信號量已經以給定名稱存在,則創建信號量可能失敗。 我不明白爲什麼打開信號失敗。

有些人可以澄清創建信號量&開放信號失敗的場景。

+0

是否要設置訪問限制,還是你認爲訪問限制是問題? – 2009-09-22 17:05:01

+0

這裏訪問限制是問題。由於信號量是由另一個進程較早創建的,我想使用Win32 :: Semaphore發佈信號量 – 2009-09-22 19:31:59

回答

1

Win32::Semaphore

$semaphore = Win32::Semaphore->new($initial, $maximum, [$name])

構造一個新的信號量對象。 $ initial是初始計數,$最大值是信號量的最大計數值 。如果$ name被省略或undef,則創建一個未命名的信號量對象 。

如果$ name表示現有的信號量對象,則忽略$ initial和$ maximum 並打開該對象。如果發生這種情況,$^E將設置爲183 (ERROR_ALREADY_EXISTS)。

如果我正確地讀這篇文章,如果您對Win32::Semaphore->new呼叫指的是現有的信號,那麼new通話將開啓信號,以及,其後open通話將多餘的(這不是我清楚如果你打開一個已經打開的sempahore,應該發生什麼?)。

也許你可以逐步完成代碼,在每一步檢查$sem以及$!$^E的值。

附加回復:Windows API確實有設置信號燈的訪問控制方法,但

  1. 它們不會出現Perl的Win32::Semaphore模塊中暴露
  2. 訪問控制不能除非它已經被創建信號量的其他進程所允許

我不知道你是否有任何這個問題的好選擇。你能修改創建信號量的過程來放寬訪問限制嗎?請問Win32::Semaphore作者更新他的模塊?試着自己修復Win32::Semaphore

+0

嗨, 感謝您的回覆。 $^E設置爲「訪問被拒絕」的兩種情況下,我的意思是創建信號量和打開信號量。 信號量在運行此片段之前已經由另一個進程創建。 有沒有什麼辦法可以在創建使用Win32 :: Semaphore時設置信號量權限,以便它可以被所有進程訪問。 – 2009-09-21 20:22:09

3

Win32::Semaphore->new調用Windows API函數CreateSemaphore和獲取過程的默認安全描述符,這通常意味着運行相同的用戶爲你的腳本程序可以完全訪問而運行的其它賬戶的過程獲得的訪問權限。所以,對於初學者來說,你的假設是錯誤的。

您在Perl代碼中選擇的名稱直接傳遞給API函數,因此它受到與所有其他Win32內核對象相同的namespace rules的支配。

Win32 :: Semaphore沒有提供指定訪問限制的接口。即使這樣做,Windows也不會提供每個進程的權限。權限附加到用戶,而不是進程

如果您從new獲得「訪問被拒絕」,那麼表明還有另一個程序正在運行,它選擇使用同一個名稱作爲別的東西 - 也許是另一個信號量,或者其他的東西,比如事件或互斥量 - 並且該進程作爲不同的用戶運行。

如果您收到「拒絕訪問」從open,那麼,除了爲new的可能性,這可能是因爲另一個進程已經打開一個信號具有相同的名稱,但並沒有獲得完全的權限給其他用戶。 Win32::Semaphore->open請求SEMAPHORE_ALL_ACCESS permission

如果信號量已被作爲同一用戶運行的進程打開,那麼您不應該「拒絕訪問」。在這種情況下newopen都不應該失敗,儘管$^E可能持有183(ERROR_ALREADY_EXISTS)。

2

對於該記錄,我是Win32::Semaphore的作者。正如mobrule和Rob所解釋的,Windows安全性是基於用戶/組的。不可能有隻有某些進程可以訪問的信號量。如果屬於用戶的任何進程可以訪問信號量,則該用戶的任何進程都可以訪問該信號量。

通常情況下,默認訪問只允許當前用戶訪問信號量。沒有人要求能夠讓Win32 :: Semaphore指定一個非默認安全描述符,並且關聯的API不是微不足道的。如果有人創建了一個模塊來管理SECURITY_ATTRIBUTES結構,我很樂意爲Win32 :: Semaphore和相關的IPC模塊添加對它的支持。 Win32-Security似乎不是那個模塊,儘管它可能是一個開始。

如果你需要一個信號量來處理多個用戶,你現在唯一的解決方案就是在Win32 :: Semaphore之外創建信號量,並傳遞一個適當的SECURITY_ATTRIBUTES指針。你可以用C語言編寫的小型幫助程序或Inline::C來做到這一點。 (請記住,一旦創建,信號就存在,只要任何進程有一個開放的句柄,所以你的幫助程序需要保持信號柄處於打開狀態,直到你呼叫Win32::Semaphore->open就可以了。)

+0

6年後..我不需要任何花哨的東西,只是「Everyone」能夠使用名稱以「Global \」開頭的信號量(讀/寫)。請求這個最好的地方在哪裏? – Terris 2015-09-17 00:07:57