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つのシェルを開き、スクリプトを次々に実行しました。スクリプトはロックが解放されるまでブロックし、解放された後も続行します

私は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?

キューのような単純な決定論的な順序はありますか、それともカーネルは「より高度なルール」によって「ただ」選択しますか?

4

1 に答える 1

8

排他ロックを待っているプロセスが複数ある場合、どのプロセスが最初に排他ロックを取得できるかは指定されていません。特定の順序に依存しないでください。

そうは言っても、現在のカーネルコードは、ブロックされた順序でそれらを起こします。このコメントは にあり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 つのセマフォを含むセマフォ セットを作成し、それらをすべて -1 に初期化します。最初のプロセス以降のすべてのプロセスに対して、semop()そのプロセスのセマフォに対してsem_op値ゼロを実行します。これによりブロックされます。最初のプロセスが完了した後semop()、2 番目のプロセスのセマフォに対してsem_op値 1 を実行する必要があります。これにより、2 番目のプロセスが起動します。2 番目のプロセスが完了した後semop()、3 番目のプロセスのセマフォに対してsem_op値 1 を指定して実行する必要があります。

于 2010-04-14T09:36:30.020 に答える