คำสั่ง Unix ใดที่สามารถใช้เป็นสัญญาณ / ล็อคได้


34

ฉันต้องการเรียกใช้สคริปต์เชลล์ Bash หลายชุดพร้อมกัน อย่างไรก็ตามฉันต้องการหลีกเลี่ยงสภาพการแข่งขัน คำสั่ง Unix ใดที่เป็นอะตอมมิกอย่างแท้จริงที่ฉันสามารถใช้เพื่อจุดประสงค์นี้และฉันจะใช้ได้อย่างไร


คุณกำลังทำอะไรที่ต้องทำงานแบบขนาน คุณไม่สามารถแสดงการพึ่งพาในวิธีที่ช่วยให้ขนานที่make(1)จะใช้เวลามากกว่า? (เช่นทำmake -j 9ถ้าคุณมี 8 แกน) นี่เป็นข้อได้เปรียบที่เพิ่มเข้ามาของการทำงานแบบแทรกสอดด้วยความละเอียดปลีกย่อย
vonbrand

คำตอบ:


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 ...
Riccardo Murri

1
@Riccardo, FreeBSD lockf(1)มีคำสั่งที่คล้ายกัน:
Alex B

lockf(1)แม้ว่าจะไม่ทำงานในวิธีที่ใช้ในตัวอย่างนี้ ไม่สามารถใช้หมายเลขตัวอธิบายไฟล์เป็นอาร์กิวเมนต์ได้
Charley

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 :)
ลูคัสโจนส์

โปรดระวังว่า (ตาม manpage) "เมื่อไฟล์ถูกล็อคล็อคจะต้องสัมผัสอย่างน้อยทุก ๆ ห้านาทีมิฉะนั้นการล็อคจะถือว่าเก่าและการล็อคครั้งต่อไปจะสำเร็จ"
Jay

6

การเรียกระบบmkdir()เป็น atomic บนระบบไฟล์ POSIX ดังนั้นการใช้mkdirคำสั่งในลักษณะที่เกี่ยวข้องกับการเรียกเพียงครั้งเดียวเพื่อmkdir()ให้บรรลุวัตถุประสงค์ของคุณ (IOW อย่าใช้mkdir -p) rmdirแน่นอนว่าการปลดล็อกที่เกี่ยวข้องนั้น

Caveat emptor: mkdir()อาจไม่เป็น atomic บนระบบไฟล์เครือข่าย


rmdirดังนั้นจึงเป็นอะตอม
Alexej Magura

3

บางทีคำสั่ง lockfile จะทำสิ่งที่คุณต้องการ

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

ดูเหมือนว่าจะลบไฟล์ผิด
Benjamin W.

1

หากคุณใช้ระบบปฏิบัติการยูนิกซ์เท่านั้นให้ใช้ fifos คุณสามารถเขียนบันทึกการทำงานไปยัง Fifo และมีกระบวนการอ่านจากไฟล์นี้และผู้อ่านของคุณจะบล็อกใน Fifos

ไฟล์ล็อคก็โอเค แต่สำหรับสิ่งที่คุณอธิบายฉันจะไปกับ Fifos


1
คุณอธิบายรายละเอียดเกี่ยวกับวิธีที่ฟีฟ่าสามารถป้องกันสภาพการแข่งขันได้หรือไม่?
G-Man กล่าวว่า 'Reinstate Monica'

0

ตามที่โพสต์ที่นี่: " แก้ไขการล็อคในเชลล์สคริปต์ได้หรือไม่ " โดยใช้เครื่องมือFLOM (Free Lock Manager)คำสั่งการทำให้เป็นอันดับและสคริปต์เชลล์จะกลายเป็นเรื่องง่ายเหมือนการทำงาน

flom -- command_to_serialize

FLOM ช่วยให้คุณสามารถใช้กรณีการใช้งานที่ซับซ้อนมากขึ้น (การล็อกแบบกระจายผู้อ่าน / ผู้เขียนทรัพยากรตัวเลข ฯลฯ ... ) ตามที่อธิบายไว้ที่นี่: http://sourceforge.net/p/flom/wiki/FLOM%20by%20examples/

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.