Это хорошая идея, чтобы закрыть член потока класса в деструкторе класса?
Каков наилучший способ закрыть поток Boost, управляемый классом C ++, когда пришло время уничтожить объект этого класса? У меня есть класс, который создает и запускает поток на строительство и предоставляет общественностиWake()
метод, который пробуждает поток, когда пришло время выполнить некоторую работу.Wake()
метод использует мьютекс Boost и условную переменную Boost для сигнализации потока; процедура потока ожидает переменную условия, затем выполняет работу и возвращается к ожиданию.
На данный момент я закрыл этот поток в деструкторе класса, используя булеву переменную-член в качестве & quot; идущего & quot; флаг; Я очищаю флаг и затем вызываю 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
}
}
Является ли хорошей идеей закрыть поток в деструкторе класса, как этот, или я должен предоставить открытый метод, который позволяет пользователю сделать это до уничтожения объекта, когда есть больше возможностей для обработки ошибок и / или принудительно уничтожить поток, если процедура потока не может вернуться чисто или вовремя?
Очистка беспорядка моего объекта в его деструкторе привлекательна, так как он потребует меньше внимания к деталям от пользователя (абстракция, ура!), Но мне кажется, что я должен делать вещи только в деструкторе, если я могу гарантировать, что он будет полностью занят. ответственность за успешную и тщательную очистку, и есть небольшая вероятность того, что когда-нибудь код за пределами класса должен будет знать, был ли поток полностью закрыт.
Кроме того, механизм, который я использую - запись в переменную-член в объекте в стеке одного потока и чтение этой переменной в другом потоке - безопасный и вменяемый?