2010-04-14 80 views
3

即時通訊使用一個簡單的測試腳本從 http://www.tuxradar.com/practicalphp/8/11/0 這樣羊羣鎖定順序?

<?php 
$fp = fopen("foo.txt", "w"); 
if (flock($fp, LOCK_EX)) { 
    print "Got lock!\n"; 
    sleep(10); 
    flock($fp, LOCK_UN); 
} 

我打開外殼5的,另一個 腳本阻塞,直到鎖被free'ed之後執行的腳本的一個,然後繼續釋放

即時通訊並不真正在PHP的東西,但我的問題是: 任何人都知道的flock()獲得的順序?

e.g. 
t0: process 1 lock's 
t1: process 2 try_lock < blocking 
t2: process 3 try_lock < blocking 
t3: process 1 releases lock 
t4: ?? which process get's the lock? 

有一個簡單的確定性順序,如隊列或不內核「只是」挑一的「更高級的規則」?

回答

7

如果有多個進程在等待獨佔鎖定,那麼沒有指定哪個成功獲取它。不要依賴任何特定的順序。

話雖如此,當前內核代碼按照它們被阻止的順序喚醒它們。這一評論是fs/locks.c

/* Insert waiter into blocker's block list. 
* We use a circular list so that processes can be easily woken up in 
* the order they blocked. The documentation doesn't require this but 
* it seems like the reasonable thing to do. 
*/ 

如果您想擁有一組順序運行過程中,不要使用flock()。使用SysV信號量(semget()/semop())。

創建一個信號集,其中包含每個進程在第一個之後的一個信號量,並將它們全部初始化爲-1。對於第一個過程之後的每個過程,在該過程的信號量上執行semop(),並將sem_op值設置爲零 - 這會阻止它。第一個過程完成後,它應該在第二個過程的信號量上執行semop()sem_op的值爲1 - 這會喚醒第二個過程。第二個過程完成後,它應該在第三個過程的信號量上執行semop()sem_op值爲1,依此類推。

+0

我看到 也許你有一個想法如何按特定順序同步進程? 如果沒有其他方式生病必須使用羊羣 – 2010-04-14 10:53:28

+0

@John Doe:是的,使用SysV信號量。查看我的答案更新。 – caf 2010-04-14 11:33:33