В следующем классе рабочий поток запускается в конструкторе. У работника есть блокирующий вызов в очередь.
Он работает, как и ожидалось, но когда объект AsyncQueue
выходит из области видимости (по какой-либо причине), вызывается его деструктор. Также вызывается деструктор объекта simple_queue (что я проверил отладкой).
Но что происходит с рабочим? Поскольку он все еще ожидает блокирующего вызова в очередь!
Я заметил, что без вызова impl_thread_.detach();
внутри деструктора происходит сбой. Однако я не знаю, является ли это решением вообще. Что я не понимаю дополнительно: хотя объект очереди уничтожен, блокирующий вызов не вызывает исключение - фактически я установил точку останова в обработчике перехвата. Итак, что здесь происходит и как правильно реализовать этот сценарий? Я глубоко чувствую, что то, что я делаю здесь, не совсем так, как должно быть; -)
template<typename T>
class AsyncQueue
{
public:
AsyncQueue() : impl_thread_(&AsyncQueue::worker, this)
{
tq_ = std::shared_ptr<simple_queue<T>>(new simple_queue<T>);
impl_thread_.detach();
}
//~AsyncQueue() = default;
~AsyncQueue() {
std::cout << "[" << boost::this_thread::get_id() << "] destructor AsyncQueue" << std::endl;
return;
}
private:
std::thread impl_thread_;
std::shared_ptr<simple_queue<T>> tq_;
void worker()
{
try {
while (true)
{
boost::optional<T> item = tq_->deq(); // blocks
...
...
...
}
}
catch (exception const& e) {
return;
}
}
public:
...
...
};