Объяснение семафора на основе FIFO -

Вы можете подключиться кtar:

gunzip < /path/to/gz | tar tzf -

(Или с GNU tar, вы можете просто использовать | tar tz.)

1
04.11.2020, 22:43
1 ответ

Сначала общая идея

Когда вы читаете из fifo, команда чтения завершится только тогда, когда что-то будет записано в fifo. Любая команда чтения в fifo приведет к «зависанию» сценария до тех пор, пока какой-либо другой процесс не запишет в тот же fifo.

Вы можете использовать это как семафор,

  1. выполнение некоторой случайной команды X только после завершения команды чтения и
  2. Когда команда выполнена, вы пишете один раз, чтобы позволить другому процессу, использующему семафор, завершить свою команду чтения.

Теперь, чтобы разрешить запуск N начальных процессов, вы устанавливаете семафор с N командами записи в FIFO.

Таким образом, вы получаете очередь длиной N, инициализируя «семафор» N командами записи в fifo (, в данном случае привязанным к файловому дескриптору 3 ).

Чтобы повторить :, возьмите любую команду X и оберните ее в функцию f()с чтением в строке перед командой X и записью после нее и отправьте обернутую команду в качестве фонового задания(f X &). Таким образом, с уже установленными 4 командами записи 4 первых фоновых задания будут выполняться, а 5-е остановится по команде read. Таким образом, если вы добавите команду записи в оболочку после команды X, обернутая readв 5-й команде X сможет закончить (и выполнить X на следующей строке ), как только произойдет любая из первых 4 завершает работу и выполняет команду записи в оболочке.

open_sem()

  1. execможно использовать для перенаправления ввода и вывода процесса или замены текущего процесса, в этом случае он перенаправляет файловый дескриптор 3 на (запись )и из (чтение )fifo. <для входа и >для выхода. Если вы укажете execаргумент команды (, что не сделано здесь ), то оболочка bash будет уничтожена, а ее PID заменится командой. Если вы пропустите этот шаг, чтение и запись в файловый дескриптор 3 не создаст блокировки чтения и записи, которые у вас есть с fifo.
  2. удаление не обязательно, а просто способ очистки.

run_with_lock()

  1. Команда readсчитывает то, что записано в FIFO, в переменную x. В примере команда записи в fifo записывает номер состояния выхода команды X, поэтому его можно использовать для проверки того, что предыдущая команда X успешно завершила работу (код 0 ). Если переменная xне равна 0, тогда выйдите со статусом выхода в переменной x.
  2. Предполагается, что первый аргумент run_with_lock()является командой, а остальные аргументы являются аргументами этой команды. Таким образом, ("$@")&выполняет команду с аргументами в подоболочке, которая отправляется в фоновый режим.
0
20.06.2021, 07:48

Теги

Похожие вопросы