У меня есть std::thread
, который использует Повысьте-х ASIO для чтения из последовательного порта:Безопасного прерывания C++ 11 блокирует работу
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 it = asio::buffers_begin(buf.data());
string line(it, it + buf.size());
doStuffWithLine(line);
}
}
catch (std::exception e)
{
cout << "Serial thread error: " << e.what() << endl;
}
}
void SetupSignals()
{
// Arrange it so that `quit = true;` happens when Ctrl-C is pressed.
}
int main(int argc, char *argv[])
{
SetupSignals();
thread st(serialThread);
st.join();
return 0;
}
Когда я нажимаю Ctrl-C Я хочу, чтобы чисто выхода резьбы , так что все деструкторы вызываются соответствующим образом (некоторые драйверы в Windows ненавидят его, если вы не закрываете свои ресурсы должным образом).
К сожалению, как вы можете видеть, текущий код блокируется в read_until()
, поэтому, когда вы нажимаете Ctrl-C, ничего не произойдет до тех пор, пока не будет получена новая строка текста.
Одним из решений является использование опроса, что-то вроде этого:
asio::async_read_until(port, buf, "\n", ...);
while (!quit)
io.poll();
Но я предпочел бы не использовать опрос. Это довольно неэлегантно. Единственное решение, которое я вижу в настоящее время, - это иметь std::condition_variable quitOrIoFinished
, который запускается либо тогда, когда quit
установлено в значение true, или когда чтение заканчивается. Но я не писал asio, поэтому я не могу дать ему переменную условия, чтобы ждать.
Есть ли чистые разумные решения? В Go я бы просто использовал select
, чтобы ждать по нескольким каналам, где один из них - это канал выхода. Я не вижу подобного решения на C++.
Довольно точно есть способ указать тайм-аут 'asio :: read_until'. Установите этот тайм-аут, возможно, 200 мс и проверьте, следует ли вы выйти, прежде чем повторять попытку. – nwp
Да, это всего лишь менее агрессивные опросы, хотя ... Я бы хотел, чтобы не было опроса. – Timmmm