首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >防止锁传播

防止锁传播
EN

Stack Overflow用户
提问于 2012-01-15 07:14:59
回答 4查看 3.4K关注 0票数 9

在bash下执行锁定的一种简单且看似可靠的方法是:

代码语言:javascript
运行
复制
exec 9>>lockfile
flock 9

然而,bash臭名昭著地将这样的fd锁传播到所有派生的东西,包括执行的程序等。

有没有办法告诉bash不要复制fd?很棒的是,锁被附加到一个fd上,当程序终止时,无论它是如何终止的,fd都会被删除。

我知道我可以做这样的事情:

代码语言:javascript
运行
复制
run_some_prog 9>&-

但这是相当乏味的。

有没有更好的解决方案?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-01-15 07:26:30

您可以使用flock(1)-o命令行选项(长选项--close,这可能更适合于编写自文档化的脚本)来指定在通过flock(1)执行命令之前应该关闭文件描述符

代码语言:javascript
运行
复制
   -o, --close
          Close the file descriptor on which the lock is held
          before executing command.  This is useful if command
          spawns a child process which should not be holding
          the lock.
票数 9
EN

Stack Overflow用户

发布于 2012-08-08 18:11:07

显然,flock -o FD并没有解决这个问题。为了在同一shell脚本中的后续命令中消除多余的FD,有一个技巧是将剩余的部分包装到一个关闭FD的部分中,如下所示:

代码语言:javascript
运行
复制
var=outside

exec 9>>lockfile
flock -n 9 || exit
{

: commands which do not see FD9

var=exported
# exit would exit script

# see CLUMSY below outside this code snippet
} 9<&-
# $var is "exported"

# drop lock closing the FD
exec 9<&-

: remaining commands without lock

这有点CLUMSY,因为FD的关闭距离锁太远了。

你可以重构这一点,放松“自然”的命令流,但将属于一起的东西放在一起:

代码语言:javascript
运行
复制
functions_running_with_lock()
{
: commands which do not see FD9

var=exported
# exit would exit script
}

var=outside

exec 9>>lockfile
flock -n 9 || exit

functions_running_with_lock 9<&-

# $var is "exported"

# drop lock closing the FD
exec 9<&-

: remaining commands without lock

一种更好的编写方式,它以牺牲另一个分支以及额外的进程和稍微不同的工作流程为代价来保持自然的命令流,这通常会很方便。,但这不允许在外壳中设置变量

代码语言:javascript
运行
复制
var=outside

exec 9>>lockfile
flock -n 9 || exit
(
exec 9<&-

: commands which do not see FD9

var=exported
# exit does not interrupt the whole script
exit
var=neverreached
)
# optionally test the ret if the parentheses using $?

# $var is "outside" again

# drop lock closing the FD
exec 9<&-

: remaining commands without lock

顺便说一句,如果你真的想确保bash不会引入额外的文件描述符(为了“隐藏”关闭的FD并跳过真正的fork),例如,如果你执行一些守护进程,然后它将永远持有锁,推荐使用后一种变体,只是为了确认一下。lsof -nPstrace your_script是你的朋友。

票数 4
EN

Stack Overflow用户

发布于 2012-01-15 07:25:26

在bash中,没有办法将FD标记为close-on-exec,所以没有更好的解决方案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8866175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档