Python的日志模块是线程安全的吗?
如果你从两个不同的Python线程中调用同一个日志处理器,是否需要加锁呢?
2 个回答
5
如果你从不同的线程调用同一个处理程序,那它就是线程安全的。为了更好地理解这个问题,我再多说一点。实际上,这取决于你如何使用 logging
模块。在多个线程中记录日志时,还是有一些情况是不安全的。
比如,如果多个线程使用不同的日志记录器实例(也就是说,在每个线程中调用 logging.getLogger()
时使用不同的名字),而这些日志记录器实例都有自己的 FileHandler
,并且都指向同一个文件,那么就会出现竞争条件,这样就不再是线程安全的了。
另外,如果不同线程中的多个日志记录器实例各自持有自己的 RotatingFileHandler
或 TimedRotatingFileHandler
,而它们都指向同一个文件(也就是在创建它们时使用了相同的文件名),那么它们在轮换文件时的逻辑也不是线程安全的。当它们需要轮换文件时,可能会发生一些奇怪的事情。(你可以参考这个问题 Python TimedRotatingFileHandler - 日志丢失,原因类似)
在 logging
模块的内部,每个处理程序实例都持有一个 threading.RLock
实例,因此持有不同处理程序的不同日志记录器会持有不同的 RLock
,所以这些锁无法避免在不同线程中,日志记录器尝试写入同一个文件时出现竞争条件——即使它们各自获得了自己的 RLock
,仍然可以同时向同一个文件写入数据。
你可以参考 Logging Cookbook - 多次打开同一个日志文件 部分以获取更多信息。
57
日志模块是线程安全的;它会为你处理锁的问题。想了解更多,可以查看文档。