早上好,
我正在尝试在非常特定的环境中实现并发,并且不断陷入困境。也许你可以帮助我。
情况就是这样:
- 我有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
$@
如果没有失败,这个包装器效果很好。问题是,如果脚本在执行之前被终止,则不会执行陷阱,也不会删除控制文件。然后,当我们再次执行包装器以重新启动任务时,它将无法工作,因为每个节点都会认为其他人正在运行该应用程序。
一个可能的解决方案是在“$ @”调用之前删除控制脚本,但这会导致一些竞争条件。
有任何建议或想法吗?
感谢您的帮助。
编辑:使用正确的解决方案进行编辑,作为未来参考
答案 0 :(得分:0)
您的陷阱语法看起来不对:根据POSIX,它应该是:
trap [action condition ...]
e.g:
trap 'rm $controlFile' HUP INT TERM
trap 'rm $controlFile' 1 2 15
请注意,如果使用单引号,则在执行陷阱之前不会展开$controlFile
。