如何设置未来的添加到队列从另一个线程在Cython的结果
How to set result of futureadd 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%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()
会有帮助吗?
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 运行同一解决方案的另一个项目的项目
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- C++从另一个类访问公共静态向量的正确方法是什么
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- 使用std::transform将一个范围的元素添加到另一个范围中
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 修改函数中的指针(将另一个指针作为参数传递)
- 如何读取STD ::队列与另一个线程共享
- 另一个线程安全队列实现
- 如何创建一个将队列作为数据成员的类,该成员在 c++ 中存储另一个类的实例
- Boost:阻塞,直到队列有另一个项目
- 来自另一个线程的 SendMessage() 调用是否将消息发布到消息队列
- 将队列项目复制到另一个类对象中
- 如何在链接列表队列中将一些数据从一个节点传输到另一个节点C++
- 在另一个类中调用一个类(队列)的方法
- 将队列实例的前面复制到另一个队列实例的后面
- 如何设置未来的添加到队列从另一个线程在Cython的结果