c++ - Safely interrupt C++11 blocking operation -


i have std::thread uses boost's asio read serial port:

std::atomic<bool> quit(false);  void serialthread() {     try     {         asio::io_service io;         asio::serial_port port(io);          port.open("com9"); // yeay no port enumeration support!          port.set_option(asio::serial_port_base::baud_rate(9600));          while (!quit)         {             asio::streambuf buf;             asio::read_until(port, buf, "\n");              auto = asio::buffers_begin(buf.data());             string line(it, + buf.size());              dostuffwithline(line);         }     }     catch (std::exception e)     {         cout << "serial thread error: " << e.what() << endl;     } }  void setupsignals() {     // arrange `quit = true;` happens when ctrl-c pressed. }  int main(int argc, char *argv[]) {     setupsignals();      thread st(serialthread);      st.join();      return 0; } 

when press ctrl-c want cleanly exit thread, destructors called appropriately (some drivers on windows hate if don't close resources properly).

unfortunately can see, current code blocks in read_until() when press ctrl-c nothing happen until new line of text received.

one solution use polling, this:

asio::async_read_until(port, buf, "\n", ...); while (!quit)     io.poll(); 

but i'd rather not use polling. pretty inelegant. solution can see have std::condition_variable quitoriofinished triggered either when quit set true, or when read finishes. didn't write asio can't give condition variable wait on.

is there clean sane solution? in go use select wait on multiple channels, 1 of them quit channel. can't see similar solution in c++ though.

use asio::signal_set await int signal (control-c tends send interrupt).

when arrives, call cancel() on io objects pending asynchronous operations. return error_code equal boost::asio::error::operation_aborted.

now, if have io_service::work object, destruct , threads running io_service::run() return, can join them.

note take care of synchronizing access io objects (e.g. when invoke cancel() on them) because these objects not thread-safe, unlike io_service , strand.


Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -