Python死锁问题查找

本文主要讨论Python中由于无法获取GIL造成的死锁问题,这类死锁通常由C代码层面引起。通过实例分析,介绍如何使用gdb定位并解决此类死锁,包括attach到进程、查看堆栈、切换线程等步骤,帮助开发者有效排查问题。
摘要由CSDN通过智能技术生成
1 用Python写的程序,由于其GIL的存在,死锁的情况变得有点复杂。

2 基本上可以分成两种情况:

一种是在调用Thread.join,Queue.put,Queue.get,Lock.acquire这些函数造成的死锁,可以归结成Python代码层造成的死锁

另一种情况是由于无法获取GIL而造成的死锁,可以归结成C代码层造成的死锁,具体原因是这样的:

由于某个Python线程调用了一个C函数,而这个函数在等某一资源的释放,并且Python线程在调用这个函数之前又没有把GIL给释放掉,一直占着GIL,

造成其它的Python线程因无法获取GIL都处于死锁状态

因为这时候Python代码已经无法执行,用pydev,winpdb等工具已经无能为力了。

3 前一种情况的死锁比较好查,用pydev,winpdb查看下堆栈就可以分析出死锁的具体位置。

4 由于第一种情况的死锁原因查起来比较简单,这里重点讨论一下第二种情况的死锁问题的查找。

5 按照惯例,照样先举一个例子,这个例子从《Cython进阶--用Cython封装Callback函数》里的示例代码修改而来。

6 改动很小,只是在JoinThread这个函数里去掉了PyEval_SaveThread和PyEval_RestoreThread的调用,用于造成一个死锁的情况。


cdef extern from "pthread.h":

    ctypedef void *pthread_t

 

    ctypedef structpthread_attr_t:

       pass

 

    int pthread_create(pthread_t *__newthread, \

                  pthread_attr_t *__attr, \

                  void *(*__start_routine) (void *) except*, \

                  void *__arg)

                   

    int pthread_join(pthread_t __th, void **__thread_return)

 

 

cdef extern from "Python.h":

    ctypedef enumPyGILState_STATE:

       pass

    ctypedef enumPyThreadState:

       pass

 

    PyGILState_STATEPyGILState_Ensure()

    voidPyGILState_Release(PyGILState_STATE)

 

    PyThreadState *PyEval_SaveThread()

    voidPyEval_RestoreThread(PyThreadState *)

 

    void PyEval_InitThreads()

 

    void Py_INCREF(objectobj)

    void Py_DECREF(objectobj)

 

def Callback(obj):

    if hasattr(obj,'run'):

       obj.run()

 

cdef void * start (void * param) except*:

    cdef PyGILState_STATEstate

    cdef object obj =param

    cdef void *ret

    if not param:

       return 
    
    
     
     0

    state =PyGILState
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值