Python 在多线程状态下打印日志,是否会存在死锁问题?

2018-09-11 15:18:44 +08:00
 Buffer2Disk

如题,线上环境使用 thread.start_new_thread 启动了 10 个线程,每个线程读取数据库后,都在往同一个文件里面写入日

志,使用的是 Python 的 logging 模块

运行一段时间后,发现有 2 个线程没有写入日志了,但是其他八个线程仍然正常在写入,htop 查看该线程仍然是存在

的,这是死锁导致的吗?

网上查了下资料,logging 是线程安全的,应该是有 GIL 锁的,但是如果是死锁导致的话,其他八个线程应该也拿不

到锁才对,为什么能够继续写入呢?还是说在查数据库的时候连接超时导致的?

5104 次点击
所在节点    Python
22 条回复
linuxchild
2018-09-11 15:21:44 +08:00
看日志吧;

以前试过,日志倒是正常,当时忘记几个线程了
Buffer2Disk
2018-09-11 16:55:44 +08:00
@linuxchild 查了日志,也没啥特殊的异常报出来,很奇怪
Buffer2Disk
2018-09-11 16:56:04 +08:00
@linuxchild 你当时也是死锁了吗?
linuxchild
2018-09-11 16:56:50 +08:00
@Buffer2Disk 没,当时日志挺正常的
Buffer2Disk
2018-09-11 17:33:46 +08:00
@linuxchild 后来有解决吗?
colin8102
2018-09-11 17:49:33 +08:00
python 的多线程不是假的么?还会出现打 log 死锁?我都是使用的多进程,通信极其麻烦,
d18
2018-09-11 17:58:58 +08:00
The logging module is intended to be thread-safe without any special work needing to be done by its clients. It achieves this though using threading locks; there is one lock to serialize access to the module ’ s shared data, and each handler also creates a lock to serialize access to its underlying I/O.
文档有写。
Eds1995
2018-09-11 18:07:32 +08:00
@colin8102 io 操作时候多线程是真的,会释放 gil 的
codingcrush
2018-09-11 18:33:32 +08:00
线程安全的
reself
2018-09-11 18:41:09 +08:00
建议搞清楚文件锁和 gil 锁的区别。logging 写日志是用 append 模式打开的文件,写入时会加锁。问题在于你的使用方式下这个锁是不是线程安全的?
lniwn
2018-09-11 19:05:13 +08:00
建议单个日志线程,其他线程把 log 信息都发送到日志线程。
sampeng
2018-09-11 19:27:46 +08:00
append 还能死锁?长见识。。。
toono
2018-09-11 19:37:33 +08:00
等待下文
lolizeppelin
2018-09-11 20:02:01 +08:00
正常设置下 linux Python 多进城写日志都是安全的
luzhongqiu
2018-09-11 21:47:38 +08:00
建议,用 async 吧
justou
2018-09-12 08:33:48 +08:00
做了异常处理没有, 有可能是那两个线程异常退出了
weyou
2018-09-12 10:15:09 +08:00
可以看 logging 模块的源码,是做了线程同步的。实际使用中也从未发现有 logging 导致的死锁发生。
Buffer2Disk
2018-09-12 14:04:44 +08:00
@justou 异常处理做了,但是只看到了数据库连接超时的日志,超时的话,数据库恢复正常时,会自动重连上去的
线程异常退出的话,不知道怎么样算退出,从 htop 里面看线程还是存在的
mythmgn
2018-09-12 15:06:44 +08:00
logging 是 thread-safe 的,我们的库在 logging 的基础上实现了 cup.log 模块( https://github.com/baidu/CUP/blob/master/cup/log.py ) ,在线上跑了很久了,没问题的哈。

感觉还是楼主的代码逻辑哪儿有问题导致卡住了,肯定不是 logging 导致的。
Buffer2Disk
2018-09-12 17:50:17 +08:00
@mythmgn 我也觉得,如果是 logging 死锁了的话,其他几个线程不会继续正常写入的,
那个线程里面里面就做了 3 件事情 :1.读取远程数据库的数据 2.打印日志 3.开启或者关闭 socket 端口
第一件事情实际测试过,数据库挂掉过几分钟又重新启动后,线程是不会阻塞的,可以继续正常读取数据
打印了异常日志,也没发现什么特别的,就数据库挂掉后,读取超时的日志,
但是现在就出现个玄学问题了,怎么能排查出来问题在哪?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/488208

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX