[英]ls this code thread-safe?
我正在重構一些耗時的函數,以便可以從線程中調用它,但是我無法解決這個問題(對線程編程不是很熟悉)。
在任何時候,用戶都可以取消,該功能將停止。 我不想在用戶取消后立即殺死該線程,因為它可能導致某些數據完整性問題。 相反,我將在函數的多個位置檢查函數是否已取消,如果已取消,則退出。 我只會在我知道可以安全退出的情況下這樣做。
該函數的整個代碼將在互斥鎖內。 這是我想到的偽代碼:
SomeClass::SomeClass() {
cancelled_ = false;
}
void SomeClass::cancelBigSearch() {
cancelled_ = true;
}
void SomeClass::bigSearch() {
mutex.lock();
// ...
// Some code
// ...
// Safe to exit at this point
if (cancelled_) {
mutex.unlock();
cancelled_ = false;
return;
}
// ...
// Some more code
// ...
if (cancelled_) {
mutex.unlock();
cancelled_ = false;
return;
}
// ...
// Again more code
// ...
if (cancelled_) {
mutex.unlock();
cancelled_ = false;
return;
}
mutex.unlock();
}
因此,當用戶開始搜索時,新線程將調用bigSearch()
。 如果用戶取消, cancelBigSearch()
調用cancelBigSearch()
並設置cancelled_
標志。 然后,當bigSearch()
到達可以安全退出的位置時,它將退出。
知道這是否全部是線程安全的嗎?
您應該使用另一個互斥鎖來鎖定對cancelled_
訪問,因此檢查和設置不會同時發生。 除此之外,我認為您的方法還可以
更新:另外,請確保不能從SomeClass::bigSearch()
拋出任何異常,否則互斥體可能會保持鎖定狀態。 為了確保所有返回路徑都可以解鎖互斥鎖,您可能希望用if (!cancelled_)
包圍代碼的處理部分,並僅在方法的最后返回(在該方法的最后一個調用unlock()
互斥體。
更好的是,將互斥體包裝在RAII( 資源分配是初始化 )的對象中,因此,無論函數如何結束(異常或其他方式),都可以保證互斥體被解鎖。
是的,這是線程安全的。 但:
cancelled_
副本,通常互斥鎖同步功能會應用適當的緩存同步。 cancelled_
。 一些特定於平台的命令可以在這里提供幫助,或者您可以簡單地使用其他機制。 所有這些導致線程沒有按您希望的那樣及時取消。
您的代碼使用模式是簡單的“信號發送”。 因此,您需要將信號傳輸到線程。 信號模式允許多次觸發相同的觸發(信號),並稍后將其清除。
可以使用以下方法進行模擬:
它不是線程安全的,因為一個線程可以同時讀取cancelled_
,而另一個線程向它寫入,這是數據競爭,這是未定義的行為。
正如其他人所建議的那樣,可以將原子類型用於cancelled_
或使用另一個互斥體對其進行保護。
您還應該使用RAII類型來鎖定互斥鎖。
例如
void SomeClass::cancelBigSearch() {
std::lock_guard<std::mutex> lock(cxlMutex_);
cancelled_ = true;
}
bool SomeClass::cancelled() {
std::lock_guard<std::mutex> lock(cxlMutex_);
if (cancelled_) {
// reset to false, to avoid caller having to lock mutex again to reset it
cancelled_ = false;
return true;
}
return false;
}
void SomeClass::bigSearch() {
std::lock_guard<std::mutex> lock(mutex);
// ...
// Some code
// ...
// Safe to exit at this point
if (cancelled())
return;
// ...
// Some more code
// ...
if (cancelled())
return;
// ...
// Again more code
// ...
if (cancelled())
return;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.