为什么在这个bash代码中flock死锁?

时间:2015-04-28 13:30:01

标签: bash makefile flock

这可能是一个愚蠢的问题,但我只是看不到它。

我正在创建一个gmake生成文件来构建我们的系统,如in this question所述。我希望makefile能够同时构建调试版本和发布版本(也许是一个很大的错误,但让我们将它分开)。一如既往,棘手的部分是构建依赖关系。现在,我正在让两个版本重建依赖项文件,并使用sed使每个依赖项文件同时使用debug&发布版本。

代码类似于以下内容:

(flock 200 ; umask 002 ; $(FORTRAN) $(STD_FOR_OPTS) -O2 \
 -gen-dep=$(task_SRCDIR)$(<F).d $(INCLUDEPATH) $(FFLAGS) -c $< -o $@ ; \
 sed -e [stuff to remove a pesky abberent line] \
     -i $(task_SRCDIR)$(<F).d; \
 flock -s 200 ; flock -x 201 ; cp $(task_SRCDIR)$(<F).d $(task_DEPDIR)$(<F).d; \
 sed -e [fairly standard dependency editing per various sources] \
     < $(task_SRCDIR)$(<F).d >> $(task_DEPDIR)$(<F).d; \
 rm -f $(task_SRCDIR)$(<F).d) \
200>$(task_SRCDIR)$(<F).d 201>$(task_DEPDIR)$(<F).d

-gen-dep选项来自我们必须使用的英特尔编译器套件。)

通常,一切都可以找到。 sed命令执行正确的编辑,所有这些命令都适用于世界......除了发生死锁的罕见,不可预测的情况。此代码同时针对调试运行(尽管使用-g -debug而不是-O2),并使用静态模式规则和绝对目录发布版本。

如果我使用make -j 4 all调用makefile,我会同时停止两个flock 200语句( flock -s 200根据ps -O cmd)如果两者之间存在内核级竞争条件。调用shell的目标是相同的.d文件,这是有道理的,因为它们是应该使用它们的唯一两个文件。但是,我不明白为什么一个flock 200没有获得批准,但两者都是封锁的。

所有文件都在同一个本地文件系统上;没有涉及NFS flakiness(至少目前没有)。

忽略了以不同方式做出依赖关系的明显决策(无论如何我都在考虑这种情况),使用模板(后面的另一个考虑因素)等等,flock 200如何在这里陷入僵局?

编辑我刚刚阅读了以下here

  

最后,如果锁定文件被删除,即使某些东西持有旧锁,后续锁定尝试也会成功。因此,如果您要保护对任意资源的访问权限,请注意锁定文件的访问控制权限。您不希望任何人从您下面删除该文件。

也许我应该在flock -u 200之后明确rm ...

0 个答案:

没有答案