fl fl fd跨子进程:如果我使用相同的fd,我冒险将它分配给其他进程锁吗?

时间:2016-08-22 12:29:15

标签: bash concurrency flock

我正在编写一个运行多个进程(连续)的多进程bash脚本,我需要启动一些函数,每个函数都有一个类似于man for flock中描述的形式:

function1 () {
    #.... preamble, variable initialization
    (
             flock -x -w 10 200 || exit 1
             # ... my commands ....
    ) 200>/var/lock/.`basename $0`$conf"-rtrr.lock"
}

每个函数都有自己的fd(数字)与其他函数不同,每个函数都独立于其他函数。

期望的行为是我应该能够并行运行多次相同的函数,唯一的条件是函数及其参数描述的只有一个实例可以在每个时刻运行。 如果函数执行失败,则父项运行在一个无限循环中并再次启动它,这不是问题。 例如,如果我们将此视为正在运行的进程/函数的列表:

OK
function1 a
function1 b
function2 a
function3 b

NO:
function1 a
function1 a
function2 b
function3 b

在每个部分,我使用类似的东西指定不同的锁定文件名:

/var/lock/${program_name}-${parameter}-${function_name}.lock 

示例lockfile,如果使用:

调用function1
/var/lock/program-a-function1.lock

问题:

  1. 在几个进程中使用相同的fd编号,启动相同的功能,我冒一个子进程覆盖另一个子进程的fd映射的风险吗?风险在于进程可能会等待错误的锁定。
  2. 我可以将变量用作fd吗?例如,一个数字,它是一种参数哈希?
  3. 否则,有没有办法在使用flock命令时不使用fd?
  4. 您认为,对于这种期望的行为,最好使用简单的文件来获取和释放锁:ieg在获取时创建文件,在发布时删除文件并在if上面检查锁定文件的存在?

1 个答案:

答案 0 :(得分:0)

  1. 没风险。当子进程在某个文件描述符槽中打开文件时,它将掩盖继承的文件描述符(如果一个继承到该槽中)
  2. 你可以,但这是不明智的。为了获得最大的可移植性,您应该使用小于10的内容。例如,如flock手册页示例中那样。
  3. 是的,正如flock手册页所描述的那样,但这意味着执行一个不适合你的情况的命令。
  4. 听起来不必要复杂
  5. 如果我是你,我会创建一个>的锁文件,其名称将来自$0(scriptname),${FUNCNAME[0]}(函数名)和{{1} (函数参数的串联)并将它们与像flock联机帮助页中的9这样的小文件描述符一起使用。如果在脚本名$ 0上使用basename,请执行一次并将结果保存在全局中。

    示例代码:

    $*

    示例代码的可能输出:

    #!/bin/bash
    
    script_name="$(basename "$0")"
    
    func1()(
        echo "$BASHPID: Locking $(readlink /dev/fd/9)"
        flock 9 || return 1
        echo "$BASHPID: Locked $(readlink /dev/fd/9)"
        echo "$BASHPID: WORK"
        sleep 1
        echo "$BASHPID: Release $(readlink /dev/fd/9)"
    ) 9>/var/lock/"$script_name-${FUNCNAME[0]}-$*"
    
    
    func1 a & 
    func1 a & 
    func1 a & 
    func1 b & 
    func1 b & 
    func1 b & 
    
    wait