Які команди Unix можна використовувати як семафор / блокування?


34

Я хочу запустити паралельно кілька сценаріїв оболонки Bash. Однак я хочу уникати перегонів. Які команди Unix є справді атомними, які я міг би використовувати для цієї мети, і як я можу їх використовувати?


Що ви робите, що вимагає паралельної роботи? Чи не можете ви виразити залежності таким чином, що дозволяє паралелі make(1)перебирати? (тобто зробіть, make -j 9якщо у вас є 8 ядер)? Це має додаткову перевагу переплетення роботи з тонкою деталізацією.
фонбранд

Відповіді:


30

Якщо lockfileвін не встановлений у вашій системі, тоді mkdirбуде виконуватися робота: це атомна операція, і вона виходить з ладу, якщо каталог вже існує (до тих пір, поки ви не додасте -pкомутатор командного рядка).

create_lock_or_wait () {
  path="$1"
  wait_time="${2:-10}"
  while true; do
        if mkdir "${path}.lock.d"; then
           break;
        fi
        sleep $wait_time
  done
}

remove_lock () {
  path="$1"
  rmdir "${path}.lock.d"
}

26

flock(1)

#!/bin/bash

# Makes sure we exit if flock fails.
set -e

(
  # Wait for lock on /var/lock/.myscript.exclusivelock (fd 200) for 10 seconds
  flock -x -w 10 200

  # Do stuff

) 200>/var/lock/.myscript.exclusivelock

Це гарантує, що код між "(" і ")" запускається лише одним процесом за один раз і що процес чекає блокування занадто довго.


Гарний, не знав про це. Однак це, мабуть, специфічно для Linux ...
Ріккардо Муррі

1
@Riccardo, FreeBSD має аналогічну команду: lockf(1).
Алекс Б

lockf(1)не працює так, як використовується в цьому прикладі. Він не може приймати номер дескриптора файлу як аргумент.
Чарлі

11

lockfile (1) виглядає як хороший кандидат, проте будьте уважні, що це частина пакета procmail , який ви, можливо, ще не встановили на своїй машині. Це досить популярний пакет, що його слід упакувати для вашої системи, якщо він ще не встановлений. У трьох із чотирьох систем, які я перевірив, вони є, а в іншій є.

Використовувати його просто:

#!/bin/sh
LOCKFILE=$HOME/.myscript/lock
mkdir -p `dirname $LOCKFILE`

echo Waiting for lock $LOCKFILE...
if lockfile -1 -r15 $LOCKFILE
then
    # Do protected stuff here
    echo Doing protected stuff...

    # Then, afterward, clean up so another instance of this script can run
    rm -f $LOCKFILE
else
    echo "Failed to acquire lock!  lockfile(1) returned $?"
    exit 1
fi

Опції, які я дав, змушують його повторити раз на секунду до 15 секунд. Відкиньте прапор "-r", якщо ви хочете, щоб він чекав вічно.


2
Тільки для довідки - чоловіча сторінка: linux.die.net/man/1/lockfile . :)
Лукас Джонс

Майте на увазі, що (відповідно до сторінки сторінки) "Щойно файл заблокований, його потрібно торкатися щонайменше раз на п’ять хвилин, або блокування вважатиметься застарілим, і наступні спроби блокування будуть успішними".
Джей

6

У mkdir()файлових системах POSIX системний виклик є атомним. Отже, використовуючи mkdirкоманду таким чином, що вона передбачає рівно один дзвінок, щоб mkdir()досягти вашої мети. (IOW, не використовувати mkdir -p). Відповідне розблокування, rmdirзвичайно.

Caveat emptor: mkdir()може бути не атомним у мережевих файлових системах.


rmdirтому є також атомним?
Олексій Магура

3

Можливо, команда lockfile виконає все, що вам потрібно.

lockfile ~/.config/mylockfile.lock
.....
rm -f important.lock

Це, здається, видалить неправильний файл.
Бенджамін В.

1

Якщо ви працюєте лише на Unix, використовуйте fifos. Ви можете писати робочі записи на файл fifo і мати з них прочитані процеси, і ваші читачі блокуються на файлі.

Файли блокування в порядку, але для того, що ви описуєте, я б пішов з фіфосом


1
Не могли б ви детальніше розповісти, як ви думаєте, як фіфос може запобігти умовам перегонів?
G-Man каже: "Відновіть Моніку"

0

Як зазначено тут: " Правильне блокування скриптів оболонки? ", За допомогою інструмента FLOM (Free LOck Manager) , серіалізація команд та скриптів оболонки стає так само просто, як і запуск

flom -- command_to_serialize

FLOM дозволяє реалізувати більш складні випадки використання (розподілене блокування, читачі / записи, числові ресурси тощо), як пояснено тут: http://sourceforge.net/p/flom/wiki/FLOM%20by%20examples/

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.