Подтвердить что ты не робот

Как я могу достоверно сказать, если поток boost вышел из своего метода запуска?

Я предположил, что joinable укажет на это, однако, похоже, это не так.

В рабочем классе я пытался указать, что он все еще обрабатывал предикат:

bool isRunning(){return thread_->joinable();}

Не мог ли поток, который вышел, не быть совместимым? Что мне не хватает... в чем смысл boost thread:: joinable?

4b9b3361

Ответ 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

Это не может быть прямым ответом на ваш вопрос, но я вижу концепцию потока как действительно легкий механизм и намеренно лишен всего, кроме механизмов синхронизации. Я думаю, что правильное место для установки "работает" находится в классе, который определяет функцию потока. Обратите внимание, что с точки зрения дизайна вы можете выйти из потока на прерывание и не выполнить свою работу. Если вы хотите очистить поток после его завершения, вы можете поместить его в безопасный указатель и передать его рабочему классу.