简体   繁体   English

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

[英]Signal handlers and logging in Python

Documentation for logging module says that 日志模块的文档说明了这一点

If you are implementing asynchronous signal handlers using the signal module, you may not be able to use logging from within such handlers. 如果使用信号模块实现异步信号处理程序,则可能无法在此类处理程序中使用日志记录。 This is because lock implementations in the threading module are not always re-entrant, and so cannot be invoked from such signal handlers. 这是因为线程模块中的锁实现并不总是可重入的,因此不能从这样的信号处理程序中调用。

This suggests that one should not make logging calls from the code invoked by the signal handler directly or indirectly. 这表明不应该直接或间接地从信号处理程序调用的代码中进行日志记录调用。 If you do once in a while program will be left is a state when only kill -9 helps. 如果你偶尔执行一次程序,那么只剩下kill -9有帮助的状态。

Important question for me now is following. 现在重要的问题是如下。 Can this locking problem also happen when other threads call logging methods at the time when main thread is processing a signal ? 其他线程主线程处理信号调用日志记录方法时,是否也会发生此锁定问题?

Signal handlers need special handling in UNIX programming at all. 信号处理程序在UNIX编程中需要特殊处理。 Only a defined list of POSIX C functions are declared as reentrant and can be called within a POSIX signal handler. 只有定义的POSIX C函数列表被声明为可重入,并且可以在POSIX信号处理程序中调用。 IEEE Std 1003.1 lists 118 reentrant UNIX functions you find at https://www.opengroup.org/ (login required). IEEE Std 1003.1列出了您在https://www.opengroup.org/找到的118个可重入的UNIX函数(需要登录)。

But Python signals are asynchronous: The signal module have an clarification: 但Python信号是异步的: 信号模块有一个澄清:

Although Python signal handlers are called asynchronously as far as the Python user is concerned, they can only occur between the “atomic” instructions of the Python interpreter. 虽然就Python用户而言,Python信号处理程序是异步调用的,但它们只能出现在Python解释器的“原子”指令之间。 This means that signals arriving during long calculations implemented purely in C (such as regular expression matches on large bodies of text) may be delayed for an arbitrary amount of time. 这意味着在纯C中实现的长计算期间到达的信号(例如大文本上的正则表达式匹配)可能会延迟一段任意时间。

In this case, signals in Python are postponed until the GIL is free . 在这种情况下,Python中的信号被推迟,直到GIL 空闲

Back to your question. 回到你的问题。 No , as long you use re-entrant functions within signal processing function. ,只要您在信号处理功能中使用重入功能。 If logging is used in threads only, there will be no problems. 如果仅在线程中使用日志记录,则不会出现问题。

The GIL (Global Interpreter Lock) prevents any Python code from running at the same time, so technically the main thread can't process a signal while other threads are running. GIL(全局解释器锁)防止任何Python代码同时运行,因此从技术上讲,主线程在其他线程运行时无法处理信号。 It may "appear" that way but there is one big mutex that only allows one python thread to run at a time. 它可能会“出现”,但有一个大的互斥锁只允许一次运行一个python线程。

The best I can guess, the problem with signals and threading is that a signal is normally caused by an interrupt which can happen at anytime. 我能猜到的最好的是,信号和线程的问题在于信号通常是由中断引起的,这种中断可能随时发生。 So I would imagine Python stops what it's doing and calls the handler. 所以我想象Python会停止正在做的事情并调用处理程序。 At this point a lock may already have been acquired and so if logging tries to lock again, you get a deadlock. 此时可能已经获取了锁,因此如果日志记录尝试再次锁定,则会出现死锁。 In some implementations this works OK because the mutex can be locked multiple times (re-entrant) but others there is only one lock. 在某些实现中,这可以正常工作,因为互斥锁可以多次锁定(重入),但其他锁定只有一个锁。

Hopefully someone else can back this up. 希望其他人可以支持这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM