2012-02-08 37 views
7

Tôi có một boost::thread thực hiện đồng bộ lần đọc trên boost::asio::serial_port. Khi tôi phá hủy một thể hiện của lớp có chứa cả hai, tôi muốn thread kết thúc một cách duyên dáng ngay cả khi nó bị chặn trong một cuộc gọi đã đọc. Tôi có thể làm cái này như thế nào?Bỏ chặn đồng bộ đọc trên tăng :: asio :: serial_port

Nhìn vào docs, tôi đã thử cancel, nhưng nó chỉ hoạt động cho các lần đọc/ghi không đồng bộ. Sau đó, tôi đã thử close, nhưng tôi có ngoại lệ và đó không phải là loại bạn có thể khôi phục. Có thể sử dụng send_break hoặc native_handle? (Đây là Windows và tính di động không phải là quan trọng)

Cập nhật: Tôi cũng đã cố gắng để stop các io_service tôi được truyền cho constructor đối tượng cổng của sê-ri, nhưng read chưa được bỏ chặn.

Chỉnh sửa: Ngoại lệ thực sự là "bắt được", nhưng tôi không muốn đặt khối try/catch bên trong một destructor, và tái cấu trúc mã để thực hiện quá trình tắt bên ngoài destructor sẽ kích hoạt nhiều thay đổi lớp trên. Vì vậy, tôi chỉ đi cho giải pháp này nếu một số cơ quan Tăng cường nói rằng không có cách nào khác.

Trả lời

5

Không có cách nào để bỏ chặn đọc đồng bộ khi bạn yêu cầu.

Có hai lựa chọn:

  • close/shutdown cảng và bắt một ngoại lệ, mà đã được nâng lên
  • sử dụng không đồng bộ đọc và cancel họ, khi bạn tắt máy ứng dụng của bạn

Các đầu tiên, tất nhiên, không phải là một ý tưởng tốt, bởi vì bạn không thể phân biệt ứng dụng chấm dứt từ lỗi.

+2

Và đó là lý do tại sao Boost :: Asio không được gọi là Boost :: SioAndAsio :) –

+0

Bạn có nghĩa là tăng :: asio :: serial_port không có nghĩa là được đọc hoặc viết đồng bộ? Tôi đã đi đọc/ghi đồng bộ để tránh bỏ phiếu ... Nếu họ cho phép tôi đọc và viết theo cách đó, hoạt động tuyệt vời và không lãng phí chu kỳ CPU, họ nên đưa ra một cách để kết thúc một cách duyên dáng. –

+0

Có, tôi muốn làm điều tương tự vài ngày trước. –

1

Khi đóng, bạn nói rằng bạn nhận được ngoại lệ 'không phải là loại bạn có thể khôi phục từ'.

Điều này có nghĩa là gì?

Giải pháp có vẻ là để nắm bắt ngoại lệ. Tại sao bạn không thể làm điều đó?

Đối với trường hợp khi bạn muốn phân biệt giữa lỗi và chương trình chấm dứt, hãy đặt cờ khi chấm dứt chương trình trước khi đóng. Trong xử lý ngoại lệ (bắt) kiểm tra cờ. Nếu được đặt, hãy xử lý như chấm dứt chương trình, nếu không thì sẽ xử lý như lỗi.

Bạn nói rằng bạn không muốn đặt một khối try/catch bên trong một destructor. Điều này có vẻ như là một thành kiến ​​kỳ lạ đối với tôi, nhưng OK có nhiều cách khác.

  1. Bạn có thể cho phép ngoại lệ lan truyền tất cả các cách đến khối catch trên cùng bao quanh tất cả mã của bạn và xử lý ở đó. (Bạn có một khối try/catch như vậy bảo vệ toàn bộ ứng dụng của bạn, tất nhiên :-)

  2. Các cách khác cũng có thể ...nhưng ông chủ chỉ cần bỏ qua

+0

Tôi thực sự bỏ qua các trường hợp ngoại lệ và nhấn tiếp tục trong trình gỡ lỗi, nhưng vì nó xảy ra bên trong một destructor, nó irked tôi quá nhiều quá đặt một khối try/catch đó. Tôi có thể refactor mã của tôi để làm điều này bên ngoài destructor, nhưng điều này sẽ gợn lên nhiều lớp destructors cuộc gọi và sẽ được khá khó chịu. Tôi sẽ chỉ chấp nhận điều này như là một giải pháp cuối cùng. Tôi đã chỉnh sửa câu hỏi của mình cho phù hợp. –

+0

Về ngoại lệ trong destructors, [có những cạm bẫy] (http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.9). Nhưng tôi nghĩ rằng kịch bản nguy hiểm được đề cập trong faq không áp dụng. Bên cạnh đó, tôi hỏi tại danh sách mail người dùng tăng cường và họ nói với tôi để bắt 'tăng :: asio :: lỗi :: operation_aborted', cho phép tôi phân biệt tắt máy từ lỗi, tôi tin. Tôi sẽ thử điều này và nếu nó hoạt động, tôi sẽ chấp nhận câu trả lời của bạn. –

+0

Tôi đã cố gắng để bắt 'std :: exception' và chạy vào Runtime Kiểm tra thất bại # 0 (giá trị của ESP không được bảo quản hoặc một cái gì đó như thế). Tôi đã từ bỏ và quyết định sử dụng async_read và viết + Tăng cường sự kiện Windows tương đương để thực hiện chặn đọc và viết. –

Các vấn đề liên quan