2012-02-08 180 views
7

我有一個boost::thread執行同步讀取一個boost::asio::serial_port。當我銷燬包含兩者的類的實例時,我希望線程能夠優雅地結束,即使它在讀取調用中被阻塞。我怎樣才能做到這一點?阻止同步閱讀的boost :: ASIO :: serial_port

看着docs,我試過cancel,但它只適用於異步讀/寫。然後我嘗試了close,但是我得到了一個異常,它不是您可以從中恢復的那種。也許使用send_breaknative_handle? (這是Windows和便攜性不是關鍵)

更新:我也試圖stopio_service我傳遞給串口對象的構造,但read不暢通。

編輯:唯一的例外是實際上是「開捕」,但我討厭把一個try/catch塊析構函數裏面,重構代碼來執行關機過程外的析構函數會引發很多的變化上層。所以如果一些Boost權威人士說沒有別的辦法,我只會選擇這個解決方案。

回答

5

按照您的要求,無法解鎖同步讀取。

有兩種選擇:

  • close/shutdown港口和捕捉異常,這是引發
  • 使用異步讀取和cancel它們,當你關閉你的應用程序

的第一個當然不是一個好主意,因爲你無法區分終止應用程序和錯誤。

+2

下降,這就是爲什麼的boost ::短耳不叫的boost :: SioAndAsio :) – 2012-02-09 14:14:05

+0

你的意思是提高:: ASIO :: serial_port並不意味着要讀取或寫入同步?爲了避免輪詢,我進行了同步讀/寫操作......如果他們允許我以這種方式進行讀寫操作,這種方法奇妙並且不會浪費CPU週期,它們應該提供一種優雅地結束的方式。 – 2012-02-09 14:37:35

+0

是的,我想在幾天前做同樣的事情。 – 2012-02-09 14:47:00

1

在接近,你說你會得到一個異常「是不是你可以從恢復的那種」。

這是什麼意思?

該解決方案似乎是爲了趕上例外。你爲什麼不能那樣做?

當你想一個錯誤,程序終止區分的情況下,在收盤前設置程序終止的標誌。在異常處理程序(catch)中檢查標誌。如果設置,則作爲程序終止來處理,否則作爲錯誤處理。

你說你不希望放置一個try/catch塊析構函數中。這對我來說似乎是一種奇怪的偏見,但確定還有其他方法。

  1. 您可以允許例外,一路圍繞所有代碼的最頂層catch塊傳播,並處理它。 (你有這樣的try/catch塊保護整個應用程序,當然:-)

  2. 其它方式也是可能的...但老闆只是

+0

我實際上忽略了異常,並在調試器中繼續,但由於它發生在析構函數內部,所以它也讓我感到厭煩,因此在那裏放置了一個try/catch塊。我可以重構我的代碼在析構函數之外執行此操作,但這會摧毀許多層析構函數調用,並且會非常麻煩。我只會接受這是最後的解決辦法。我相應地編輯了我的問題。 – 2012-02-10 20:20:00

+0

關於析構函數中的異常,[有陷阱](http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.9)。但我認爲在常見問題解答中提到的危險情況並不適用。另外,我在boost-users郵件列表中詢問,他們告訴我要抓住'boost :: asio :: error :: operation_aborted',這讓我可以區分關機和錯誤,我相信。我會試試這個,如果它有效,我會接受你的答案。 – 2012-02-14 20:26:45

+0

我試圖捕捉'std :: exception'並且遇到運行時檢查失敗#0(ESP的值沒有保存或類似的東西)。我放棄了,並決定使用async_read和寫+ Boost Windows事件相當於執行阻止讀取和寫入。 – 2012-02-17 13:14:27