Python 板


LINE

程式执行登入时需要在另一个装置做一些认证 在认证完成前原本程式的 UI 可以取消登入 但是此时做认证的 thread block 在一个 3rd party lib 等待认证回应的 function 所以不能用一般在 thread 下 check event 的方式来决定要不要离开 Google 了一下,找到利用 thread-id raise exception 的方式 http://stackoverflow.com/questions/323972/is-there-any-way-to-kill-a-thread-in-python shorten: http://goo.gl/MRRDFA 但是怎麽试也无法成功...都是 invalid thread ID 尝试用文中的 walk 找 tid,或是用 threading.current_thread().ident 得到的都是一个很长的数字,也许不是真正的 tid? 所以试着用 system call 的方式 libc = ctypes.cdll.LoadLibrary('libc.so.6') tid = libc.syscall(186) 的方式来得到 tid 但是丢进去 PyThreadState_SetAsyncExc 里还是 invalid tid... 也就是 return 是 0 请问该如何得到正确的 tid? 或是有其他方式可以 kill thread? (最好是 portable 的) 也顺便问问是否有其他更好的做法可以避免需要 kill thread? --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 1.34.244.41
※ 文章网址: http://webptt.com/cn.aspx?n=bbs/Python/M.1408672998.A.6E2.html ※ 编辑: carylorrk (1.34.244.41), 08/22/2014 10:20:57
1F:推 LiloHuang: 我想先说明,终止线程跟 OS 本身有极高的相关性 08/22 20:45
2F:→ LiloHuang: 我印象中目前并无某种方法,或某个内建的 API 08/22 20:45
3F:→ LiloHuang: 可以保证的在所有的系统上,终止某个特定线程。 08/22 20:46
4F:→ LiloHuang: 至少 Win32 得用 TerminateThread,不同於 pthread 08/22 20:46
5F:→ LiloHuang: 我先假设你所使用的作业系统所操作的是 pthread 08/22 20:46
6F:→ LiloHuang: 无论是透过 get_ident 或用 ident 都是拿到 pthread_t 08/22 20:46
7F:→ LiloHuang: 也就是 pthread_self() 会拿到的内容 (可查源码参照) 08/22 20:46
8F:→ LiloHuang: 你拿到的数值会有点大,我猜你的系统应该是 64 bit 08/22 20:46
9F:→ LiloHuang: StackOverflow 那则被打勾的回应是常见的好方法 08/22 20:47
10F:→ LiloHuang: 至少这个方式不是真正强制硬砍掉 Thread 运行 08/22 20:47
11F:→ LiloHuang: 然而之所以你会拿到 invalid thread ID 的原因是 08/22 20:47
12F:→ LiloHuang: 你得改所有用到 PyThreadState_SetAsyncExc 的部分 08/22 20:47
13F:→ LiloHuang: foobar = ctypes.pythonapi.PyThreadState_SetAsyncExc 08/22 20:47
14F:→ LiloHuang: foobar.argtypes = [ctypes.c_long, ctypes.py_object] 08/22 20:47
15F:→ LiloHuang: res = foobar(tid, ctypes.py_object(exctype)) 08/22 20:48
16F:→ LiloHuang: 请把原文章中的 _async_raise 前几行,适度修改如上 08/22 20:48
17F:→ LiloHuang: 如此一来就应该不会出现 invalid thread ID 的状况 08/22 20:49
18F:→ LiloHuang: 原因是在 64 bit 的环境中,得写清楚带进去的资料型态 08/22 20:50
19F:→ LiloHuang: 再透过 _async_raise(thr.ident, RuntimeError) 来终止 08/22 20:51
20F:推 LiloHuang: 至於是否有更好的做法? 可以开 child process 也是一种 08/22 20:53
21F:→ LiloHuang: 可以把伤害摆到另外一个进程,尽管还是会有机率出状况 08/22 20:55
22F:→ LiloHuang: 最好的方式是改 3rd party lib 使其 graceful exit :D 08/22 20:55
23F:→ LiloHuang: 行有余力还可以顺便 merge 回 master/trunk 之类的 XD 08/22 20:57
感谢你的回覆,後来发现里面推文就有了 忘记来这边改XD 果然发文之前要好好爬文啊~ 摆到另外一个 process 的方式下面推文也有,不过感觉其实是差不多的~ 至於改 code... trace 了一下里面有使用 requests 这个 lib 用 session.get() 经过 verification 抓 json 会造成 block 比较好的方式是改用 async 的方法再去 busy wait 要中断就 set flag 结束 while loop 这样 XD? 可惜不能 merge 回去,因爲这段 code 最近因爲被某 L 社要求撤掉了 Orz ※ 编辑: carylorrk (1.34.244.41), 08/23/2014 00:07:49
24F:推 LiloHuang: 其实我也没仔细看所有回应,只是要说 ctypes 在 64bit 08/23 00:14
25F:→ LiloHuang: 的环境得多设定 argtypes 或者直接类似该讨论串中某篇 08/23 00:15
26F:→ LiloHuang: 直接生出 c_long(tid) 再进行带入的动作... 08/23 00:15
27F:→ LiloHuang: 最好的方式就是用 event / mutex 实作 graceful exit 08/23 00:15
28F:→ LiloHuang: 或者用一个 atomic variable 来当作 stop flag 之类的 08/23 00:16
29F:→ LiloHuang: 毕竟没看到 3rd party lib 的原始码,我只能猜到这 XD 08/23 00:18
30F:推 LiloHuang: 至於 Python 还有个 GIL,如果用一些强制力砍掉 thread 08/23 00:21
31F:→ LiloHuang: 如果刚好被砍掉的 thread 是持有 GIL 的话,那就有趣了 08/23 00:21
32F:→ LiloHuang: 如果是 mission critical 的环境,就得考量更多的细节 08/23 00:23
33F:→ LiloHuang: 总之恭喜你有把问题解决罗 :D 08/23 00:24
34F:→ LiloHuang: 毕竟提及 child process 只是想避掉 GIL 这个老问题 08/23 00:27
了解~ 不过如果用 async raise 还会有 GIL 的问题吗? 毕竟不是 kill thread,应该会 release GIL 吧~ ※ 编辑: carylorrk (1.34.244.41), 08/23/2014 01:16:53
35F:推 LiloHuang: 不应该有GIL的问题,诚如我一开始提到这不是强制砍掉它 08/23 01:35
36F:→ LiloHuang: 所谓的强制力是指 pthread_kill or TerminateThread 08/23 01:37
37F:→ LiloHuang: 然而如果能实作 graceful exit 还是最好的方向就是 :) 08/23 01:38
38F:推 LiloHuang: 因为 PyThreadState_SetAsyncExc 是请求触发 exception 08/23 01:58
39F:→ LiloHuang: 并不会真的立刻把该 thread 给终止掉,听起来虽然不错 08/23 01:59
40F:→ LiloHuang: 然而如果该 thread 不幸卡在一个很久的 blocking I/O 08/23 02:01
41F:→ LiloHuang: 或者该 thread 刚好操作某个会卡很久的 C-API 08/23 02:02
42F:→ LiloHuang: 就不一定能如同原本预期,顺利的把 thread 给终止掉了 08/23 02:03
43F:→ LiloHuang: 毕竟这个的原理是在 PyEval_EvalFrameEx 还没跑 opcode 08/23 02:05
44F:→ LiloHuang: 之前进行检查 tstate->async_exc 的值是否有被设定 :D 08/23 02:05
45F:→ LiloHuang: 可参考源码了解更多细节http://goo.gl/878eMi 大概如此 08/23 02:07
原来如此!如果没有解说我还真把它当神奇的黑魔法 XDD 看来还需要研究一下细节,说不定哪天手上没有 source code 就用的到了XD 感谢~ ※ 编辑: carylorrk (1.34.244.41), 08/23/2014 03:10:49







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:iOS站内搜寻

TOP