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/m.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燈, 水草

請輸入看板名稱,例如:Gossiping站內搜尋

TOP