Kno*_*abe 2 c++ multithreading c++11
另一个SO线程解释了如何使用thread::native_handleC++线程API之外的东西(例如,设置线程的优先级).要点是:
std::thread t(functionToRun);
auto nh = t.native_handle());
// configure t using nh
Run Code Online (Sandbox Code Playgroud)
这种方法的问题在于,functionToRun在配置t的代码完成之前,可以执行任意时间量(包括完成).
我相信我们可以防止这种情况发生如下(未经测试):
std::atomic<bool> configured(false);
std::thread t([&]{ while (!configured); // spin until configured is true
functionToRun(); });
auto nh = t.native_handle();
// configure t using nh
configured = true;
Run Code Online (Sandbox Code Playgroud)
不幸的是,这导致生成的线程旋转等待configured变为真.产生的线程最好在配置完成之前阻塞.
实现这一目标的一种方法似乎是使用互斥锁(也是未经测试的):
std::mutex m;
std::unique_lock<std::mutex> lock(m);
std::thread t([&]{ std::lock_guard<std::mutex> lg(m); // block until m available
functionToRun(); });
auto nh = t.native_handle();
// configure t using nh
lock.unlock(); // allow t to continue
Run Code Online (Sandbox Code Playgroud)
这似乎应该可以工作,但是,从概念上讲,似乎condvar更适合于指示何时满足条件(配置完成)的工作.但是使用condvar需要上述所有内容,加上condvar,并且需要处理虚假唤醒的可能性,据我所知,这对于互斥体来说不是问题.
是否有更好的方法来生成一个线程然后让它立即停止,以便我可以使用它的本机句柄来配置它,然后再允许它运行?
当我希望延迟线程主函数的启动,直到某些外部配置完成后,我使用未来.这避免了自旋等待,并且具有与互斥或condvar相同的阻塞属性,但提供了更清晰的意图.使用此模式,您可以将您的示例编写为:
std::promise<void> p;
std::thread t([&p]{
p.get_future().wait();
thread_func();
}
auto nh=t.native_handle();
// configure nh
p.set_value();
Run Code Online (Sandbox Code Playgroud)
我特别喜欢将这种模式shared_future用于多线程测试 - 这样你就可以确保所有线程都在运行并准备好在测试开始之前.
| 归档时间: |
|
| 查看次数: |
226 次 |
| 最近记录: |