LINUX.ORG.RU

История изменений

Исправление 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, либо через автоматическое уничтожение при выходе из области определения) и в конце будет только один мой тред.