Если это не определено, то какой будет чистый способ для нескольких потоков ждать на одном потоке?
Чистый способ был бы для этого потока, чтобы сообщить другим, что он завершен. A packaged_task
содержит future
, на который можно ждать, что может помочь нам здесь.
Вот один из способов сделать это. Я использовал std :: thread и std :: packaged_task, но вы также можете использовать эквиваленты boost.
#include <thread>
#include <mutex>
#include <future>
#include <vector>
#include <iostream>
void emit(const char* msg) {
static std::mutex m;
std::lock_guard<std::mutex> l(m);
std::cout << msg << std::endl;
std::cout.flush();
}
int main()
{
using namespace std;
auto one_task = std::packaged_task<void()>([]{
emit("waiting...");
std::this_thread::sleep_for(std::chrono::microseconds(500));
emit("wait over!");
});
// note: convert future to a shared_future so we can pass it
// to two subordinate threads simultaneously
auto one_done = std::shared_future<void>(one_task.get_future());
auto one = std::thread(std::move(one_task));
std::vector<std::thread> many;
many.emplace_back([one_done] {
one_done.wait();
// do my thing here
emit("starting thread 1");
});
many.emplace_back([one_done] {
one_done.wait();
// do my thing here
emit("starting thread 2");
});
one.join();
for (auto& t : many) {
t.join();
}
cout << "Hello, World" << endl;
return 0;
}
ожидается выход:
waiting...
wait over!
starting thread 2
starting thread 1
Hello, World
Хм, интересно, он не упоминается в N4296 C++ стандартный проект, который я могу читать. Я бы сказал, что это тогда поведение UB и/или «не делайте этого». :) – wilx
Другие потоки могли бы проверить, был ли поток «joinable()», или закрывающий поток мог использовать «condition_variable», чтобы сигнализировать, что все его работы завершены (хотя он все еще работает _may_) – Tas
@wilx, 'std :: thread :: join() 'является неконстантной функцией, поэтому одновременным вызовом является гонка данных, то есть неопределенное поведение. Это правило применяется ко всем типам стандартных библиотек, если не указано иное. –