V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Buffer2Disk
V2EX  ›  Python

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

  •  
  •   Buffer2Disk · 2018-09-11 15:18:44 +08:00 · 5068 次点击
    这是一个创建于 2025 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    志,使用的是 Python 的 logging 模块

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

    的,这是死锁导致的吗?

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

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

    22 条回复    2018-09-12 19:21:19 +08:00
    linuxchild
        1
    linuxchild  
       2018-09-11 15:21:44 +08:00
    看日志吧;

    以前试过,日志倒是正常,当时忘记几个线程了
    Buffer2Disk
        2
    Buffer2Disk  
    OP
       2018-09-11 16:55:44 +08:00
    @linuxchild 查了日志,也没啥特殊的异常报出来,很奇怪
    Buffer2Disk
        3
    Buffer2Disk  
    OP
       2018-09-11 16:56:04 +08:00
    @linuxchild 你当时也是死锁了吗?
    linuxchild
        4
    linuxchild  
       2018-09-11 16:56:50 +08:00
    @Buffer2Disk 没,当时日志挺正常的
    Buffer2Disk
        5
    Buffer2Disk  
    OP
       2018-09-11 17:33:46 +08:00
    @linuxchild 后来有解决吗?
    colin8102
        6
    colin8102  
       2018-09-11 17:49:33 +08:00
    python 的多线程不是假的么?还会出现打 log 死锁?我都是使用的多进程,通信极其麻烦,
    d18
        7
    d18  
       2018-09-11 17:58:58 +08:00   ❤️ 1
    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
        8
    Eds1995  
       2018-09-11 18:07:32 +08:00
    @colin8102 io 操作时候多线程是真的,会释放 gil 的
    codingcrush
        9
    codingcrush  
       2018-09-11 18:33:32 +08:00
    线程安全的
    reself
        10
    reself  
       2018-09-11 18:41:09 +08:00 via Android
    建议搞清楚文件锁和 gil 锁的区别。logging 写日志是用 append 模式打开的文件,写入时会加锁。问题在于你的使用方式下这个锁是不是线程安全的?
    lniwn
        11
    lniwn  
       2018-09-11 19:05:13 +08:00
    建议单个日志线程,其他线程把 log 信息都发送到日志线程。
    sampeng
        12
    sampeng  
       2018-09-11 19:27:46 +08:00
    append 还能死锁?长见识。。。
    toono
        13
    toono  
       2018-09-11 19:37:33 +08:00 via iPhone
    等待下文
    lolizeppelin
        14
    lolizeppelin  
       2018-09-11 20:02:01 +08:00 via Android
    正常设置下 linux Python 多进城写日志都是安全的
    luzhongqiu
        15
    luzhongqiu  
       2018-09-11 21:47:38 +08:00
    建议,用 async 吧
    justou
        16
    justou  
       2018-09-12 08:33:48 +08:00
    做了异常处理没有, 有可能是那两个线程异常退出了
    weyou
        17
    weyou  
       2018-09-12 10:15:09 +08:00 via Android
    可以看 logging 模块的源码,是做了线程同步的。实际使用中也从未发现有 logging 导致的死锁发生。
    Buffer2Disk
        18
    Buffer2Disk  
    OP
       2018-09-12 14:04:44 +08:00
    @justou 异常处理做了,但是只看到了数据库连接超时的日志,超时的话,数据库恢复正常时,会自动重连上去的
    线程异常退出的话,不知道怎么样算退出,从 htop 里面看线程还是存在的
    mythmgn
        19
    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
        20
    Buffer2Disk  
    OP
       2018-09-12 17:50:17 +08:00
    @mythmgn 我也觉得,如果是 logging 死锁了的话,其他几个线程不会继续正常写入的,
    那个线程里面里面就做了 3 件事情 :1.读取远程数据库的数据 2.打印日志 3.开启或者关闭 socket 端口
    第一件事情实际测试过,数据库挂掉过几分钟又重新启动后,线程是不会阻塞的,可以继续正常读取数据
    打印了异常日志,也没发现什么特别的,就数据库挂掉后,读取超时的日志,
    但是现在就出现个玄学问题了,怎么能排查出来问题在哪?
    weyou
        21
    weyou  
       2018-09-12 19:06:11 +08:00 via Android
    @Buffer2Disk 可以检查下线程有没有访问相同的数据资源,比如同一个全局量或同一个对象之类的
    mythmgn
        22
    mythmgn  
       2018-09-12 19:21:19 +08:00
    @Buffer2Disk 二分法增加 log 试试。

    这样缩小范围到具体是哪儿卡住了。 我调试多线程一般就是靠日志,哈哈。 一般玄学问题大部分都是代码逻辑问题。 真遇到编辑器或者库缺陷的,太少了,除非你直接操作了非常非常底层的东西
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1186 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 18:19 · PVG 02:19 · LAX 11:19 · JFK 14:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.