我有一段代碼模擬提供者/消費者場景,其中每個提供者和消費者都是一個執行緒。我已將每個消費者與提供者配對,消費者將等到其提供者完成(通過呼叫join()提供者執行緒)再執行。代碼如下:
std::vector<std::thread> threads;
const uint32_t num_pairs = 3;
auto provider = [&](uint32_t idx) {
/* produce resources and put them in a global container */
};
auto consumer = [&](uint32_t idx) {
/* consumer i is paired with provider (i-num_pairs) */
uint32_t provider_idx = idx - num_pairs;
threads[provider_idx].join();
assert(threads[provider_idx].joinable() == false);
/* access the resources */
};
for (uint32_t i = 0; i < 2 * num_pairs; i ) {
if (i < num_pairs) {
/* 0, 1, 2 are providers */
threads.emplace_back(provider, i);
} else {
/* 3, 4, 5 are consumers */
threads.emplace_back(consumer, i);
}
}
/* join the consumer threads later */
大多數情況下它作業正常,但有時斷言consumer失敗并且提供者執行緒在加入后仍然可以加入。實施是不正確的還是我不知道發生了什么?請提前幫助和感謝!
uj5u.com熱心網友回復:
當您將執行緒推入其中時,該向量threads正在增長,很有可能一些執行緒將在您完成添加所有執行緒之前開始執行。當向量容量增加時,所有迭代器和對它的參考變得無效。這意味著在threads[provider_idx]回傳的參考中,可能在[]運算子回傳和執行緒方法執行之間無效。由于這是未定義的行為,因此您觀察到的不當行為join并不joinable出人意料。
在創建執行緒之前保留向量的大小應該可以解決問題:
threads.reserve(2 * num_pairs);
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/457407.html
上一篇:如何在后面的代碼中生成一個復選框并將其作為子項發送到MainWindow的邊框?
下一篇:狀態在任務中被取消,沒有使用令牌進行初始化,并且在lambda中使用ThrowIfCancellationRequested呼叫
