如何将 future\add 的结果设置为从 Cython 中的另一个线程排队?
How to set result of future\add to queue from another thread in Cython?
我有 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%i\n", (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
.cpp http://pastebin.com/MeygA8im
这有点猜测,但您可能有一个 Cython/C/C++ 循环 运行 持有 GIL 并且从不释放它。然后强制回调永远等待它。
在正常的 Python 代码中,如果另一个线程正在等待 GIL,每隔几条指令就会释放 GIL。在 Cython 中,这不会自动发生。确保它确实经常发生的一种方法是循环:
while True:
# ... do stuff
with nogil:
pass
这确保每个循环释放一次 GIL。
不幸的是,我不清楚你的主循环在哪里。我想知道它是否在您的 PyTeamSpeak3
class 中的 connect
内,并且可能将连接的定义更改为:
def connect(self):
with nogil:
self.thisptr.Connect()
可能有帮助?
我有 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%i\n", (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
.cpp http://pastebin.com/MeygA8im
这有点猜测,但您可能有一个 Cython/C/C++ 循环 运行 持有 GIL 并且从不释放它。然后强制回调永远等待它。
在正常的 Python 代码中,如果另一个线程正在等待 GIL,每隔几条指令就会释放 GIL。在 Cython 中,这不会自动发生。确保它确实经常发生的一种方法是循环:
while True:
# ... do stuff
with nogil:
pass
这确保每个循环释放一次 GIL。
不幸的是,我不清楚你的主循环在哪里。我想知道它是否在您的 PyTeamSpeak3
class 中的 connect
内,并且可能将连接的定义更改为:
def connect(self):
with nogil:
self.thisptr.Connect()
可能有帮助?