История изменений
Исправление KivApple, (текущая версия) :
Я обычно делаю хитрее. Каждый тред хранится в каком-то экземпляре класса. Что-то вроде:
class FileDownloader {
std::thread m_thread;
std::atomic_flag m_running;
public:
...
~FileDownloader() {
m_running.clear();
m_running.notify_one(); // Если используется wait
m_thread.join();
}
};
Соответственно, уничтожая экземпляр класса я автоматически завершаю поток (разумеется, в функции потока есть регулярная проверка m_running в том или ином виде). У меня нет ни одного моего треда, который бы не имел владельца в виде объекта. Соответственно, главный тред в том или ином виде уничтожит всех владельцев (явным delete, либо через автоматическое уничтожение при выходе из области определения) и в конце будет только один мой тред. Плюс такого подхода по сравнению с глобальной переменной заключается в том, что я могу контролировать порядок завершения тредов, а также механизм обобщается с завершения при выходе на завершение тредов в середине работы приложения (например, допустим, юзер нажал кнопку отмены закачки - обработчик этой кнопки просто сделает delete экземпляру FileDownloader, при этом остальные треды продолжат работу, ведь юзер не закрыл приложение).
Исправление KivApple, :
Я обычно делаю хитрее. Каждый тред хранится в каком-то экземпляре класса. Что-то вроде:
class FileDownloader {
std::thread m_thread;
std::atomic_flag m_running;
public:
...
~FileDownloader() {
m_running.clear();
m_running.notify_one(); // Если используется wait
m_thread.join();
}
};
Соответственно, уничтожая экземпляр класса я автоматически завершаю поток (разумеется, в функции потока есть регулярная проверка m_running в том или ином виде). У меня нет ни одного моего треда, который бы не имел владельца в виде объекта. Соответственно, главный тред в том или ином виде уничтожит всех владельцев (явным delete, либо через автоматическое уничтожение при выходе из области определения) и в конце будет только один мой тред. Плюс такого подхода по сравнению с глобальной переменной заключается в том, что я могу контролировать порядок завершения тредов, а также механизм обобщается с завершения при выходе на завершение тредов в середине работы приложения (например, допустим, юзер нажал кнопку отмены закачки - обработчик этой кнопки просто сделает delete экземпляру FileDownloader).
Исходная версия KivApple, :
Я обычно делаю хитрее. Каждый тред хранится в каком-то экземпляре класса. Что-то вроде:
class FileDownloader {
std::thread m_thread;
std::atomic_flag m_running;
public:
...
~FileDownloader() {
m_running.clear();
m_running.notify_one(); // Если используется wait
m_thread.join();
}
};
Соответственно, уничтожая экземпляр класса я автоматически завершаю поток (разумеется, в функции потока есть регулярная проверка m_running в том или ином виде). У меня нет ни одного моего треда, который бы не имел владельца в виде объекта. Соответственно, главный тред в том или ином виде уничтожит всех владельцев (явным delete, либо через автоматическое уничтожение при выходе из области определения) и в конце будет только один мой тред.