在易出故障的环境中使用shell脚本实现并发

时间:2015-09-24 07:43:35

标签: linux bash shell concurrency

早上好,

我正在尝试在非常特定的环境中实现并发,并且不断陷入困境。也许你可以帮助我。

情况就是这样:

- 我有N个节点可以在共享文件夹中读/写。

- 我想在其中一个中执行一个应用程序。这可以是任何东西,如shell脚本,已安装的代码或其他任何东西。

- 要这样做,我必须向所有人发送相同的命令。第一个应该开始执行,其余的应该看到其他人正在运行所需的应用程序并退出。

- 可以随时终止应用程序的执行。这很重要,因为在执行后不允许依赖任何清洁步骤。

- 如果应用程序被杀死,用户可能希望再次执行它。然后他会发出同样的命令。

我目前的方法是创建一个包装要执行的命令的shell脚本。这也可以用C. not python或其他语言实现,以避免库依赖。

#!/bin/sh
# (folder structure simplified for legibility)
mutex(){
  lockdir=".lock"
  firstTask=1 #false

  if mkdir "$lockdir"  &> /dev/null
  then
    controlFile="controlFile"

    #if this is the first node, start coordinator
    if [ ! -f $controlFile ]; then
      firstTask=0 #true
      #tell the rest of nodes that I am in control
      echo "some info" > $controlFile
     fi

     # remove control File when script finishes
     trap 'rm $controlFile' EXIT
  fi
  return $firstTask
}


#The basic idea is that a task executes the desire command, stated as arguments to this script. The rest do nothing
if  ! mutex ;
then
  exit 0
fi

#I am the first node and the only one reaching this, so I execute whatever
$@

如果没有失败,这个包装器效果很好。问题是,如果脚本在执行之前被终止,则不会执行陷阱,也不会删除控制文件。然后,当我们再次执行包装器以重新启动任务时,它将无法工作,因为每个节点都会认为其他人正在运行该应用程序。

一个可能的解决方案是在“$ @”调用之前删除控制脚本,但这会导致一些竞争条件。

有任何建议或想法吗?

感谢您的帮助。

编辑:使用正确的解决方案进行编辑,作为未来参考

1 个答案:

答案 0 :(得分:0)

您的陷阱语法看起来不对:根据POSIX,它应该是:

trap [action condition ...]

e.g:

trap 'rm $controlFile' HUP INT TERM
trap 'rm $controlFile' 1 2 15

请注意,如果使用单引号,则在执行陷阱之前不会展开$controlFile