Какие команды Unix можно использовать в качестве семафора/блокировки?

Какие команды Unix можно использовать в качестве семафора/блокировки?

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

решение1

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

Это гарантирует, что код между «(» и «)» будет выполняться только одним процессом одновременно, и что процесс не будет слишком долго ожидать блокировки.

решение2

Если 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"
}

решение3

lockfile(1) выглядит как хороший кандидат, хотя имейте в виду, что он является частьюпрокмейлпакет, который вы, возможно, еще не установили на своей машине. Это достаточно популярный пакет, который должен быть упакован для вашей системы, если он еще не установлен. В трех из четырех систем, которые я проверил, он есть, а в другой он доступен.

Использовать его просто:

#!/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", если хотите, чтобы он ждал вечно.

решение4

Возможно, команда lockfile сделает то, что вам нужно.

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

Связанный контент