Какой лучший способ отключить поток Boost, управляемый классом С++, когда это время для уничтожения объекта этого класса? У меня есть класс, который создает и запускает поток при построении и предоставляет общедоступный метод Wake()
, который пробуждает поток, когда придет время для выполнения какой-либо работы. В методе Wake()
используется мутекс Boost и переменная условия Boost для сигнализации потока; процедура потока ожидает переменную условия, затем выполняет работу и возвращается к ожиданию.
В настоящий момент я закрываю этот поток в деструкторе класса, используя логическую переменную-член как флаг "running"; Я очищаю флаг, а затем вызываю notify_one() в переменной условия. Затем процедура потока просыпается, замечает, что "работает" является ложным и возвращается. Здесь код:
class Worker
{
public:
Worker();
~Worker();
void Wake();
private:
Worker(Worker const& rhs); // prevent copying
Worker& operator=(Worker const& rhs); // prevent assignment
void ThreadProc();
bool m_Running;
boost::mutex m_Mutex;
boost::condition_variable m_Condition;
boost::scoped_ptr<boost::thread> m_pThread;
};
Worker::Worker()
: m_Running(true)
, m_Mutex()
, m_Condition()
, m_pThread()
{
m_pThread.reset(new boost::thread(boost::bind(&Worker::ThreadProc, this)));
}
Worker::~Worker()
{
m_Running = false;
m_Condition.notify_one();
m_pThread->join();
}
void Worker::Wake()
{
boost::lock_guard<boost::mutex> lock(m_Mutex);
m_Condition.notify_one();
}
void Worker::ThreadProc()
{
for (;;)
{
boost::unique_lock<boost::mutex> lock(m_Mutex);
m_Condition.wait(lock);
if (! m_Running) break;
// do some work here
}
}
Хорошо ли закрывать поток в деструкторе класса, как это, или я должен предоставить публичный метод, который позволяет пользователю сделать это до уничтожения объекта, когда есть больше возможностей для обработки ошибок и/или принудительного разрушая поток, если процедура потока не может вернуться в чистоту или своевременно?
Очистка моего объекта беспорядка в его деструкторе привлекательна, поскольку для пользователя потребуется меньше внимания к деталям (абстракция, ура!), но мне кажется, что я должен делать что-то только в деструкторе, если я могу гарантировать полная ответственность за очистку вещей успешно и тщательно, и есть небольшая вероятность того, что код вне класса может однажды узнать, действительно ли поток был закрыт.
Кроме того, я использую механизм - запись в переменную-член в объекте в стеке одного потока и чтение этой переменной в другой потокобезопасной и разумной?