信号处理程序和Python中的日志记录

时间:2011-01-05 07:16:38

标签: python logging signals

Documentation for logging module

  

如果使用信号模块实现异步信号处理程序,则可能无法在此类处理程序中使用日志记录。这是因为线程模块中的锁实现并不总是可重入的,因此无法从这些信号处理程序中调用。

这表明不应该直接或间接地从信号处理程序调用的代码中进行日志记录调用。如果你偶尔执行一次程序,那么只剩下kill -9有帮助的状态。

现在重要的问题是如下。当其他线程在主线程处理信号时调用日志记录方法时,是否也会发生此锁定问题?

2 个答案:

答案 0 :(得分:8)

信号处理程序在UNIX编程中需要特殊处理。只有定义的POSIX C函数列表被声明为可重入,并且可以在POSIX信号处理程序中调用。 IEEE Std 1003.1列出了您在https://www.opengroup.org/找到的118个可重入的UNIX函数(需要登录)。

但是Python信号是异步的:signal module有一个澄清:

  

虽然Python信号处理程序是   就异步而言是异步调用的   对Python用户而言,他们可以   只发生在“原子”之间   Python的说明   翻译。这意味着信号   在长时间的计算中到达   纯粹用C语言实现(如   正则表达式匹配大   文本的主体可能会延迟   任意的时间。

在这种情况下,Python中的信号被推迟,直到GIL free

回到你的问题。 ,只要您在信号处理功能中使用可重入函数。如果仅在线程中使用日志记录,则不会出现问题。

答案 1 :(得分:2)

GIL(全局解释器锁)阻止任何Python代码同时运行,因此从技术上讲,主线程在其他线程运行时无法处理信号。它可能会“出现”,但有一个大的互斥锁只允许一次运行一个python线程。

我能猜到的最好,信号和线程的问题在于信号通常是由中断引起的,这可能在任何时候发生。所以我想象Python会停止正在做的事情并调用处理程序。此时可能已经获取了锁,因此如果日志记录尝试再次锁定,则会出现死锁。在某些实现中,这可以正常工作,因为互斥锁可以多次锁定(重入),但其他锁定只有一个锁。

希望其他人可以支持。