如何设置未来的添加到队列从另一个线程在Cython的结果

How to set result of futureadd to queue from another thread in Cython?

本文关键字:队列 另一个 线程 结果 Cython 添加 何设置 设置 未来      更新时间:2023-10-16

我有多线程工作的c++ dll。所以我用Cython包装了这个库,并创建了一个特殊的接收器回调函数,它必须向asyncio.Queue添加一些结果。

cdef void __cdecl NewMessage(char* message) nogil:

我把它标记为nogil,这个回调从另一个线程调用。在这个回调中,我只使用了:

with gil:
   print("hello")  # instead adding to Queue. print("hello") is more simple operation to demostrate problem

在这里得到死锁。如何解决?

c++回调声明(头):

typedef void (*receiver_t)(char*);
void SetReceiver(receiver_t new_rec);

cpp:

static receiver_t receiver = nullptr;
void SetReceiver(receiver_t new_rec)
{
    printf("setted%in", (int)new_rec);
    a = 123;
    if (new_rec != nullptr)
        receiver = new_rec;
}

Cython代码:

cdef extern from "TeamSpeak3.h":
    ctypedef void (*receiver_t) (char*) nogil
    cdef void __cdecl SetReceiver(receiver_t new_rec) nogil
cdef void __cdecl NewMessage(char* message) nogil:
    with gil:
        print("hello")
SetReceiver(NewMessage)

完整代码:. h http://pastebin.com/ZTCjc6NA

http://pastebin.com/MeygA8im

. cpp

。pyx http://pastebin.com/k4X9c54P

. py http://pastebin.com/1YV7tMiF

这是一个猜测,但你可能有一个Cython/C/c++循环运行,它持有GIL,永远不会释放它。然后强制回调永远等待它。

在普通Python代码中,如果另一个线程正在等待GIL,则每隔几条指令释放GIL。在Cython中,这不会自动发生。确保这种情况经常发生的一种方法是将循环写入:

while True:
   # ... do stuff
   with nogil:
      pass

确保GIL在每个循环中被释放一次。

不幸的是,我不清楚主循环在哪里。我想知道它是否在你的PyTeamSpeak3类的connect内,也许改变连接的定义:

def connect(self):
    with nogil:
       self.thisptr.Connect()

会有帮助吗?