我正在撰寫一個 C 代碼來在不同的執行緒上執行任務并等待結果回傳到主函式。
每個執行緒可能需要不同的時間,并可能導致正確或不正確的結果。
我開始執行緒如下:
std::thread p1(&process1, (void*)&p1Data);
std::thread p2(&process2, (void*)&p2Data);
std::thread p3(&process3, (void*)&p3Data);
.
.
.
(以這種方式創建了多個執行緒)。
流程功能可以總結如下:
\\ThreadData is a structure that contains all the data for the thread
void process1(void *data)
{
ThreadData * tData = (ThreadData*) data;
ResultObject * result = data->result;
.
.
.
\\Process to calculate Result using data
}
在啟動這些執行緒后,我加入它們以等待最終結果,然后檢查正確的結果。
p1.join();
p2.join();
.
.
.
p1result = p1Data.result;
p2result = p2Data.result;
.
.
.
.
.
.
if (p1result)
{
return p1Data;
}
if (p2result)
{
return p2Data;
}
但問題是(為了簡單起見,我會認為 p1 是最快的執行緒)如果 p1 以正確的結果完成,我仍然被迫等待所有其他執行緒的連接以在 p1 完成時獲得我的最終結果第一個可以包含正確的,我可以終止它。
如果結果正常,我如何在每個執行緒完成時檢查它,以便我可以終止剩余的執行緒而無需等待它們完成(即,如果 p2 在 p1 之前完成并且 p2 的結果是可以接受的,我可以回傳 p2Data 并且不終止所有剩余的執行緒)
uj5u.com熱心網友回復:
不幸的是,沒有std::shared_promise原子set_if_still_empty()和is_empty()方法。此外,執行緒不能從外部終止(這是一件好事),C 20 用std::jthread它的停止標記解決了它,隨意使用它。我將只使用std::atomic_bool標志。在這兩種情況下,執行緒本身必須監視令牌并在請求時終止自身。
我的解決方案用于std::promise存盤結果,如果結果已經設定并且它的設定器是原子的,它就會拋出,所以不需要額外的鎖。
#include <future>
#include <thread>
#include <atomic>
using result_t=int;
void worker(std::promise<result_t>& promise,std::atomic_bool& stop_requested){
//periodically check flag
while(!stop_requested){
// do work
// if result
result_t result=1;
try{
promise.set_value(result);
// Terminate other threads soon, including us.
stop_requested=true;
return; // Not need if there is no work after `try` statement.
}
catch(const std::future_error&)//Already set
{
return;
}
}
}
int main() {
std::promise<result_t> promise;
std::atomic_bool stop_token= false;
std::thread w1(worker,std::ref(promise),std::ref(stop_token));
auto future = promise.get_future();
result_t result = future.get();
// All threads should terminated soon after they check the token.
//stop_token=true;// Is not necessary because it is set by the winning thread.
w1.join();
}
或者,std::optional<result_t>也可以使用 lock。但是您必須定期鎖定以檢查結果是否存在并且執行緒應該退出。
uj5u.com熱心網友回復:
您需要使用互斥鎖在執行緒本身內實作同步機制。
當一個執行緒終止時,它可以告訴其他執行緒他們可以通過鎖定互斥鎖、寫入結果并釋放互斥鎖來提前終止(在執行緒中使用 std::terminate)。然后每個執行緒必須查找它們是否可以定期提前終止。
請參閱:如何在 C 11 中終止執行緒?
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/366708.html
