我有一個應用程序,允許用戶使用我們自己的語言編寫自己的代碼,這有點像C++。但是,我們遇到了問題,有時我們的用戶會意外地在腳本中寫入無限循環。一旦腳本進入無限循環,他們可以退出的唯一方法就是關閉應用程序並重新啓動,可能會失去工作。我想添加一些方法,當用戶意識到他的代碼處於無限循環時,可以按F10之類的特殊鍵,代碼就會跳出循環。但是我希望不用在腳本運行時執行大量的檢查。最好,我希望有一個單獨的「調試器」線程,它大部分是空閒的,但作爲其任務之一,它監聽F10鍵,當它獲得F10鍵時,它將導致腳本運行時線程拋出異常,以便它將停止執行腳本。所以我的問題是,有沒有辦法讓一個線程導致另一個線程拋出異常?我的應用程序是用C++編寫的。跨線程異常拋出
跨線程異常拋出
回答
這是可能的。例如,在單獨的線程,隱藏的窗口和WM_HOTKEY中檢測擊鍵。調用SuspendThread()來凍結解釋器線程。現在使用GetThreadContext()獲取解釋器線程的CPU寄存器。將CONTEXT.Eip修改爲一個函數的地址並調用SetThreadContext()。讓該函數調用RaiseException()或拋出一個C++異常。 ResumeThread()和繁榮。
簡短的回答 - 沒有。
如果你的應用程序在Windows上運行,也許你可以從這個「調試器」的步伐發送消息,並在主要的消息循環?
如果腳本實際上是由應用程序解釋的,那麼只要告訴解釋器在發生某些用戶事件時就停止執行。
該解決方案的問題是,爲了做一個消息發送實現,我必須設置一個「偵聽器」作爲腳本解釋器的一部分。目前,解釋器只是執行該功能。消息循環在解釋器之外實現。如果在函數中有一個無限循環,那麼爲了突破這個腳本,我將不得不在檢查解釋器中每條指令的執行之間的一條消息,也就是說,當(更多指令){檢查F10,執行腳本指令}。這似乎是很多額外的不必要的檢查,可能會減慢腳本執行速度。但如果這是唯一的解決方案,那麼我想這就是它的原因。我仍然認爲應該有更好的方法。也許腳本解釋器需要在子線程上運行,而主線程繼續它的消息循環,然後在獲得F10時終止腳本解釋器線程。
「這個解決方案的問題是,爲了做一個消息發送實現,我必須在腳本解釋器中設置一個'listener'」聽起來很像「我想要這個新功能,但我不想不想改變代碼來獲取它。「對不起,但我認爲你需要更改代碼。 – 2009-01-15 22:42:24
終止線程是不安全的,因爲它可能使用跨整個進程共享的資源。
終止整個過程並不安全,但這不會幫助你。
解決此問題的一種更安全的方法是讓解釋器定期檢查事件並將停止事件視爲終止事件(或至少溢出到更高的循環)。對於Windows,您也可以將APC排隊到調用RaiseException(...)
或引發異常的那個線程(儘管我會避免後者,因爲它跨越了API邊界),但是這也意味着線程將把自己放入一個可警告的狀態。我並不真的推薦它。
無論您是否明確編碼,都需要在消息循環中檢查「中斷」變量。如果你通過一個簡單的volatile int
實現這個,你將會有一個非常簡單的測試和很少的開銷。
- 1. 跨線程異常
- 2. 獲取Visual Studio以跨線程拋出異常
- 3. 用戶控件拋出異常「跨線程操作無效」
- 4. 線程中拋出錯誤(異常)
- 5. 如何從線程拋出異常?
- 6. junit在線程拋出異常
- 7. 在線程池中拋出異常
- 8. 異常線程「main」拋出java.lang.ClassNotFoundException:MaxTemperature
- 9. 在UI線程上拋出異常
- 10. 多線程拋出異常列表
- 11. 拋出UI線程的異常
- 12. 拋出異常的線程C#
- 13. 的std ::線程創建拋出異常
- 14. Titan中的多線程拋出異常
- 15. 修復跨線程異常
- 16. 跨線程調用異常
- 17. BindingSource和跨線程異常
- 18. 魔術異常拋出拋出異常
- 19. 拋出異常拋出異常
- 20. 致命異常:java.lang.IllegalStateException:致命異常在Scheduler.Worker線程上拋出
- 21. 嵌套線程是否可以爲父線程拋出異常?
- 22. 從不同的線程訪問GUI線程拋出異常
- 23. 中斷主調用線程如果子線程拋出異常
- 24. 拋出異常不拋出
- 25. 異常拋出異常
- 26. 拋出異常
- 27. 異常拋出
- 28. 拋出異常
- 29. 拋出異常
- 30. 拋出異常
試過這個,它工作得很好。謝謝!!! – 2009-03-23 20:56:17