std :: thread, который не является глобальной переменной, но не выходит из области видимости, когда достигнут конец создавшей его функции? - PullRequest
0 голосов
/ 06 сентября 2018

Итак, я наткнулся на что-то, что, кажется, побеждает цель std::thread или, по крайней мере, делает ее менее удобной.

Скажем, я хочу порождать std::thread для выполнения задачи один раз и не хочу беспокоиться об этом снова после этого.Я создаю thread в конце функции, поэтому std::thread скоро выйдет из области видимости, в моем случае, вероятно, пока thread еще работает.Это создает проблему с парой решений (или, по крайней мере, из тех, что я знаю).

Я могу:

A) Сделать std::thread глобальной переменной, чтобы она не работалавне области видимости.

B) Вызовите join() на std::thread, который побеждает цель порождения потока.

Существуют ли другие, надеюсь, лучшие способы справиться с такой ситуацией

Ответы [ 3 ]

0 голосов
/ 06 сентября 2018

То, что вы хотите, это std :: thread :: detach .

Он разделяет реальный поток выполнения и объект std::thread, позволяя вам уничтожить его, не присоединяясь к потокам.

0 голосов
/ 06 сентября 2018

Другой предпочтительный вариант - разрешить потоку использовать задачи из очереди задач. Для этого разделите задание на части задач и передайте их в рабочий поток. Чтобы избежать опроса, выберите condition_variable.

std::thread([&](){
                    while(running) // thread loop
                    { 
                       // consume tasks from queue
                    }
                 }).detach();
0 голосов
/ 06 сентября 2018

Вы можете использовать std::async.

async выполняет функцию f асинхронно (возможно, в отдельном потоке, который может быть частью пула потоков) и возвращает std :: future, который в конечном итоге будет содержать результат этого вызова функции.

Поскольку вы не упомянули, что вам нужно получить результат потока, нет необходимости получать будущее.

Как указано в комментариях, деструктор std :: future будет блокироваться в любом случае, поэтому вам придется переместить его в какой-то глобальный объект (и вручную управлять удалением неиспользуемых фьючерсов), или вы можете переместить его в локальная область действия асинхронно вызываемой функции.

...