Теперь я ничего не понимаю. Рассмотрим У меня есть следующий фрагмент кода (упрощенный вариант):Ожидание потока с таймаутом: freeze
#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <chrono>
const auto k_sleep = std::chrono::seconds{3};
const auto k_wait = std::chrono::seconds{1};
const auto k_repeats = 20u;
void test()
{
std::mutex m;
std::condition_variable c;
bool processed = false;
std::thread worker{[&]() {
std::this_thread::sleep_for(k_sleep);
std::unique_lock<std::mutex> lock(m);
processed = true;
lock.unlock();
c.notify_one();
}};
std::unique_lock<std::mutex> lock(m);
if(c.wait_for(lock, k_wait, [&processed]() {
return processed;
}))
{
worker.join();
std::cout << "done" << std::endl;
}
else
{
worker.detach();
std::cout << "timeout" << std::endl;
}
}
int main()
{
for(auto i = 0u; i < k_repeats; ++i)
test();
}
Несколько вопросов:
- являются ли какие-либо тупики?
- Я использую
condition_variable
(и все остальное по отношению кthread
) правильно? - есть UB?
- если все ОК, сколько раз
timeout
будет напечатано?
Как вы можете видеть, я запускаю поток и жду его (используя condition_variable
) некоторое время. Время ожидания меньше времени выполнения потока.
С как VC++ (Visual Studio 2015, v 19.00.23026) и г ++ (ст 4.8.2) У меня есть timeout
2 раза распечатаны, а затем я застрял на worker.join()
под отладчиком. Если я увеличу k_sleep
до чего-то большого (относительно k_wait
с небольшим количеством циклов), например, 30 секунд - все будет хорошо.
Итак, почему это происходит? Если я сделаю что-то неправильно, объясните мне правильный путь. Благодаря
Вы не должны называть 'worker.detach();', но 'join()' в любом случае. –
@ πάνταῥεῖ, но я не хочу ждать потока в случае таймаута. Как я могу это сделать без вызова 'detach()' on thread? – grisha
@ πάνταῥεῖ, о, я понимаю - я использую 'condition_variable', который был уничтожен. Спасибо – grisha