порядок блокировки флок? - PullRequest
3 голосов
/ 14 апреля 2010

я использую простой тестовый скрипт из 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?

существует ли простой детерминированный порядок, такой как очередь, или ядро ​​«просто» выбирает его по «более сложным правилам»?

1 Ответ

8 голосов
/ 14 апреля 2010

Если есть несколько процессов, ожидающих эксклюзивной блокировки, не указано, какой из них преуспеет в ее получении первым. Не полагайтесь на какой-либо конкретный заказ.

Сказав это, текущий код ядра разбудит их в порядке их блокировки. Этот комментарий в 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, и т. Д.

...