Python Thread/gevent 等待 Event 完成,主线程被锁

2016-10-04 16:31:56 +08:00
 4ever911
我的程序需要调用一个第三方 C++ 写的函数 Func_from_CPP() 这个函数用了一个 WaitForSingleObject 函数,大概要处理 3 到 5 秒才能处理完成返回, 所以导致我的 UI 会被 block 掉。

所以我就想把这个函数丢到 Thread 或者 Gevent 里面去处理,等处理完成再异步通知我去对返回数据处理。

但是,奇怪的是,不管我用 thread 还是 gevent , UI 始终都是被 block 掉,都需要等函数处理完成才能返回。

是不是因为 Python 本身对线程的支持不够,导致对于 WaitForSingleObj 这样的函数,不管是否使用工作线程 /协程序,它始终是会让主线程处于等待状态?


大致代码如下:

CPP
————————————————————————————
result Func_from_CPP()
{
waitforsomeevent() //WaitForSingleObject
dowork()
return reuslt
}


python
————————————————————————————
def Work(self):
Func_from_CPP()


def onbuttonClicked(self):
Work() //直接掉用,函数调用这几秒 UI 会挂掉

threading.thread(self.Work)
threading.start() //尝试用线程来做, UI 仍然挂掉

gevent.spawn(self.Work)
gevent.sleep(0) // 第三次尝试 gevent UI 仍然挂掉



是我打开姿势不对吗?
3054 次点击
所在节点    Python
12 条回复
mooncakejs
2016-10-04 18:15:06 +08:00
我猜是 gil
alqaz
2016-10-04 19:03:07 +08:00
应该是楼上说的原因,而且 Func_from_CPP 这个函数调用了 WaitForSingleObject 函数,这是一个同步操作。 If the object's state is nonsignaled, the calling thread enters the wait state until the object is signaled or the time-out interval elapses.所以,改写这个 c++库?
Zzzzzzzzz
2016-10-04 19:25:48 +08:00
第三种只适用于 IO 堵塞, 并且 C/C++层有暴露相应的 fd 的接口可以加到 gevent 的 ioloop 里.
第二种倒是通用, 但前提是拿 C 或者 Cython 嵌一层释放 GIL 的包装.
wangxn
2016-10-04 19:34:14 +08:00
在 Func_from_CPP() 里面使用原生线程才行。如 std::thread 什么的。
4ever911
2016-10-04 20:13:47 +08:00
现在问题是我不可能去修改那部分 cpp 代码
alqaz
2016-10-04 22:24:51 +08:00
@4ever911 封装一层试下,实在不行,就两层。
ericls
2016-10-04 22:27:19 +08:00
可以用 asyncio.run_in_executor 试一下 需要用 processpoolexecuror
zhuangzhuang1988
2016-10-04 23:20:21 +08:00
因为没有释放 Gil
zhuangzhuang1988
2016-10-04 23:25:11 +08:00
推荐看 time.sleep 的 c 实现就知道了。。
binux
2016-10-04 23:30:00 +08:00
丢进程里处理就完了呗。
4ever911
2016-10-05 14:58:06 +08:00
@binux 丢给进程处理,也要在 thread.join() 等待完成吧。还是会 block 掉主线程吧,我回头试试看。
ryd994
2016-10-05 19:46:19 +08:00
@4ever911 先不 join ,用 pipe ,这样就是 IO 问题,用线程还是 gevent 都可以

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/310529

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX