2012-02-02 94 views
4

我有一个非常复杂的Python程序。在内部它有一个使用独家(LOCK_EX)fcntl.flock来管理全局锁定的日志记录系统。实际上,无论何时转储日志消息,都会获取全局文件锁定,将消息发送到文件(与锁定文件不同),并释放全局文件锁定。死亡与羊群,叉子和终止父进程

该程序还分叉几次(日志管理设置后)。 通常一切正常。

如果父进程被杀死(并且孩子活着),我偶尔会遇到死锁。所有程序永远都会阻塞fcntl.flock()。尝试从外部获取锁也永远阻止。我必须杀死儿童方案才能解决问题。

什么是令人困惑的是,虽然锁定文件lsof显示没有进程作为持有锁!所以我不知道为什么文件被内核锁定,但没有进程被报告为持有它。

羊群有分叉问题吗?即使它不再在进程表中,死锁父母是否仍然持有该锁?我该如何着手解决这个问题?

+0

好吧,我切换到fcntl.lockf,它包装fcntl锁(而不是flock)。僵局消失了。 – UsAaR33 2012-02-02 06:00:12

+0

我怀疑这是因为flock会锁定文件描述符(仍然在子进程中退出),而fcntl使用inode/pid进行锁定。但奇怪的是,我们没有解决孩子们真正拥有羊群的问题,为什么会这样? – UsAaR33 2012-02-02 06:06:43

回答

1

lsof几乎可以肯定不会显示flock()锁,所以没有人会告诉你是否有一个锁。

flock()锁通过FD-共享(dup()系统调用,或叉和高管离开打开文件)以及任何与共享描述符可以解除锁定继承的,但如果锁已经被持有,任何企图再次锁定会阻止。所以,是的,很可能是父母锁定了描述符,然后死了,而描述符被锁定。子进程然后尝试锁定并阻止,因为描述符已被锁定。 (如果子进程锁定文件,则死亡也是如此。)

由于`fcntl()'锁是每个进程,死亡进程将释放所有锁,以便继续执行,这就是你想在这里。