Những lệnh Unix nào có thể được sử dụng như một semaphore / lock?


34

Tôi muốn chạy song song nhiều tập lệnh shell Bash. Tuy nhiên, tôi muốn tránh điều kiện chủng tộc. Những lệnh Unix nào thực sự là nguyên tử mà tôi có thể sử dụng cho mục đích này và làm cách nào tôi có thể sử dụng chúng?


Bạn đang làm gì đòi hỏi công việc song song? Bạn không thể diễn tả sự phụ thuộc theo cách cho phép song song make(1)tiếp quản? (ví dụ, làm một make -j 9nếu bạn có 8 lõi)? Điều này có thêm lợi thế của công việc xen kẽ với độ chi tiết mịn hơn.
vonbrand

Câu trả lời:


30

Nếu lockfilekhông được cài đặt trên hệ thống của bạn, thì nó mkdirsẽ thực hiện công việc: đó là một hoạt động nguyên tử và sẽ thất bại nếu thư mục đã tồn tại (miễn là bạn không thêm -pcông tắc dòng lệnh).

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

Điều này đảm bảo rằng mã giữa "(" và ")" chỉ được chạy bởi một quy trình tại một thời điểm và quy trình đó sẽ chờ khóa quá lâu.


Đẹp, không biết về nó. Tuy nhiên, nó rõ ràng là dành riêng cho Linux ...
Riccardo Murri

1
@Riccardo, FreeBSD có một lệnh tương tự : lockf(1).
Alex B

lockf(1)Mặc dù vậy, không hoạt động theo cách được sử dụng trong ví dụ này. Nó không thể lấy số mô tả tập tin làm đối số.
Charley

11

lockfile (1) trông giống như một ứng cử viên tốt, mặc dù vậy hãy cẩn thận rằng đó là một phần của gói procmail , mà bạn có thể chưa cài đặt trên máy của mình. Đây là một gói đủ phổ biến mà nó nên được đóng gói cho hệ thống của bạn nếu nó chưa được cài đặt. Ba trong số bốn hệ thống tôi đã kiểm tra có nó, và hệ thống còn lại có sẵn.

Sử dụng nó rất đơn giản:

#!/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

Các tùy chọn tôi đã đưa ra khiến nó thử lại một lần một giây trong tối đa 15 giây. Thả cờ "-r" nếu bạn muốn nó chờ mãi.


2
Chỉ để tham khảo - trang man: linux.die.net/man/1/lockfile . :)
Lucas Jones

Xin lưu ý rằng (theo trang chủ), "Một khi tệp bị khóa, khóa phải được chạm ít nhất một lần trong năm phút nếu không khóa sẽ bị coi là cũ và các lần thử khóa tiếp theo sẽ thành công."
Jay

6

Cuộc gọi hệ thống mkdir()là nguyên tử trên các hệ thống tập tin POSIX. Vì vậy, sử dụng mkdirlệnh theo cách mà nó liên quan đến chính xác một cuộc gọi mkdir()sẽ đạt được mục đích của bạn. (IOW, không sử dụng mkdir -p). Việc mở khóa tương ứng là rmdirtất nhiên.

Caveat emptor: mkdir()có thể không phải là nguyên tử trên các hệ thống tập tin mạng.


rmdirdo đó cũng nguyên tử?
Alexej Magura

3

Có thể lệnh lockfile sẽ làm những gì bạn cần.

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

Điều này dường như để xóa các tập tin sai.
Benjamin W.

1

Nếu bạn chỉ chạy trên Unix, hãy sử dụng fifos. Bạn có thể viết hồ sơ công việc lên fifo và có các quy trình đọc từ tệp này và độc giả của bạn sẽ chặn trên fifos.

Khóa tập tin là ok, nhưng với những gì bạn mô tả tôi sẽ đi với fifos


1
Bạn có thể giải thích về cách bạn nghĩ fifos có thể ngăn chặn điều kiện chủng tộc?
G-Man nói 'Phục hồi Monica'

0

Như được đăng ở đây: " Khóa chính xác trong shell script? ", Sử dụng công cụ FLOM (Free LOck Manager) , việc tuần tự hóa các lệnh và shell script trở nên dễ dàng như khi chạy

flom -- command_to_serialize

FLOM cho phép bạn triển khai các trường hợp sử dụng nhẹ nhàng hơn (khóa phân tán, độc giả / nhà văn, tài nguyên số, v.v.) như được giải thích tại đây: http://sourceforge.net/p/flom/wiki/FLOM%20by%20examples/

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.