pthreads
是未定義的行爲,如果多個線程試圖加入同一個線程:多個線程可以加入相同的boost :: thread嗎?
如果多個線程同時嘗試與同一個線程加入, 結果是不確定的。
對於boost::thread
s也是如此嗎?該文檔似乎沒有指定這一點。
如果它是未定義的,那麼多線程等待一個線程完成的乾淨方式是什麼?
pthreads
是未定義的行爲,如果多個線程試圖加入同一個線程:多個線程可以加入相同的boost :: thread嗎?
如果多個線程同時嘗試與同一個線程加入, 結果是不確定的。
對於boost::thread
s也是如此嗎?該文檔似乎沒有指定這一點。
如果它是未定義的,那麼多線程等待一個線程完成的乾淨方式是什麼?
如果它是未定義的,那麼多線程等待一個線程完成的乾淨方式是什麼?
的清潔方式將是一個線程通知其他人,這是完整的。 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
我結束了使用boost::condition_variable
...大致爲:
class thread_wrapper {
boost::mutex mutex;
boost::condition_variable thread_done_condition;
bool thread_done = false;
void the_func() {
// ...
// end of the thread
{
boost:unique_lock<boost::mutex> lock(mutex);
thread_done = true;
}
thread_done_condition.notify_all();
}
void wait_until_done() {
boost::unique_lock<boost::mutex> lock(mutex);
thread_done_condition.wait(lock, [this]{ return thread_done; });
}
}
然後多個來電可以安全地調用wait_until_done()
。
這讓我覺得現在像本來還制定了以下內容:
class thread_wrapper {
public:
thread_wrapper() : thread([this]() { this->the_func(); }) { }
void wait_until_done() {
boost::unique_lock<boost::mutex> lock(join_mutex);
thread.join();
}
private:
void the_func() {
// ...
}
boost::mutex join_mutex;
boost::thread thread;
}
嗯,有趣的是,它不是在N4296 c項++標準草案,我可以讀。我會說這是UB和/或「不這樣做」的行爲。 :) – wilx
其他線程可以測試一個線程是否爲'joinable()',或者閉合線程可以使用'condition_variable'來表示它的所有工作已經完成(即使它仍然可以運行) – Tas
@wilx,'std :: thread :: join()'是一個非const函數,因此同時調用它是一個數據競爭,即未定義的行爲。除非另有規定,該規則適用於所有標準庫類型。 –