Как я могу достоверно сказать, если поток boost вышел из своего метода запуска?
Я предположил, что joinable укажет на это, однако, похоже, это не так.
В рабочем классе я пытался указать, что он все еще обрабатывал предикат:
bool isRunning(){return thread_->joinable();}
Не мог ли поток, который вышел, не быть совместимым? Что мне не хватает... в чем смысл boost thread:: joinable?
Ответы
Ответ 1
Поскольку вы можете присоединиться к потоку даже после его завершения, joinable() по-прежнему будет возвращать true до тех пор, пока вы не назовете join() или detach(). Если вы хотите узнать, работает ли поток, вы должны иметь возможность вызывать timed_join с временем ожидания 0. Обратите внимание, что это может привести к условию гонки, так как поток может завершиться сразу после вызова.
Ответ 2
Используйте thread:: timed_join() с минимальным таймаутом. Он вернет false, если поток все еще запущен.
Ответ 3
Вы принципиально не можете этого сделать. Причина в том, что два возможных ответа: "Да" и "Нет, когда я последний раз смотрел, но, возможно, сейчас". Нет надежного способа определить, что поток все еще находится внутри метода его запуска, даже если существует надежный способ определить противоположное.
Ответ 4
Я использую boost 1.54, на каком этапе timed_join() устаревает. В зависимости от вашего использования вы можете использовать функцию joinable(), которая отлично работает для моих целей, или, альтернативно, вы можете использовать try_join_for() или try_join_until(), см.
http://www.boost.org/doc/libs/1_54_0/doc/html/thread/thread_management.html
Ответ 5
Это немного грубо, но на данный момент он все еще работает для моих требований.:) Я использую boost 153 и qt. Я создал вектор int для отслеживания "статуса" моих потоков. Каждый раз, когда я создаю новый поток, я добавляю одну запись в thread_ids со значением 0. Для каждого созданного потока я передаю идентификатор, поэтому я знаю, какую часть потоков thread я должен обновлять. Установите статус 1 для запуска и другие значения в зависимости от того, какую деятельность я делаю сейчас, поэтому я знаю, что было сделано, когда поток закончился. 100 - это значение, которое я задал для правильно законченного потока. Я не уверен, поможет ли это, но если у вас есть другие предложения по улучшению этого, дайте мне знать.:)
std::vector<int> thread_ids;
const int max_threads = 4;
void Thread01(int n, int n2)
{
thread_ids.at(n) = 1;
boost::this_thread::sleep(boost::posix_time::milliseconds(n2 * 1000));
thread_ids.at(n) = 100;
qDebug()<<"Done "<<n;
}
void getThreadsStatus()
{
qDebug()<<"status:";
for(int i = 0; i < max_threads, i < thread_ids.size(); i++)
{
qDebug()<<thread_ids.at(i);
}
}
int main(int argc, char *argv[])
{
for(int i = 0; i < max_threads; i++)
{
thread_ids.push_back(0);
threadpool.create_thread(
boost::bind(&boost::asio::io_service::run, &ioService));
ioService.post(boost::bind(Thread01, i, i + 2));
getThreadsStatus();
}
ioService.stop();
threadpool.join_all();
getThreadsStatus();
}
Ответ 6
Самый простой способ, если функция, выполняющая ваш поток, достаточно прост, заключается в том, чтобы установить переменную в true, когда функция завершена. Конечно, вам понадобится переменная для потока, если у вас много карт идентификаторов потоков, и статус может быть лучшим вариантом. Я знаю, что это ручная работа, но в то же время она отлично работает.
class ThreadCreator
{
private:
bool m_threadFinished;
void launchProducerThread(){
// do stuff here
m_threadRunning = true;
}
public:
ThreadCreator() : m_threadFinished(false) {
boost::thread(&Consumer::launchProducerThread, this);
}
};
Ответ 7
Это не может быть прямым ответом на ваш вопрос, но я вижу концепцию потока как действительно легкий механизм и намеренно лишен всего, кроме механизмов синхронизации. Я думаю, что правильное место для установки "работает" находится в классе, который определяет функцию потока. Обратите внимание, что с точки зрения дизайна вы можете выйти из потока на прерывание и не выполнить свою работу. Если вы хотите очистить поток после его завершения, вы можете поместить его в безопасный указатель и передать его рабочему классу.