Порядок блокировки стада?

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

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


person John Doe    schedule 14.04.2010    source источник


Ответы (1)


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

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

person caf    schedule 14.04.2010
comment
Я вижу, может быть, у вас есть идея, как синхронизировать процессы в определенном порядке? если нет другого пути, придется использовать стадо - person John Doe; 14.04.2010
comment
@John Doe: Да, используйте семафоры SysV. Смотрите обновление к моему ответу. - person caf; 14.04.2010
comment
fs/locks.c чем пользуется flock? - person John Bachir; 01.02.2020
comment
@JohnBachir: да. - person caf; 02.02.2020
comment
@caf В моих экспериментах flock не обеспечивает справедливой очереди. Но, может быть, справедливость может быть достигнута только тогда, когда одна и та же программа использует возможности locks.c? code.jjb.cc/linux-flock-does-not- обеспечить честную блокировку - person John Bachir; 02.02.2020