我正在撰寫一個應該使用多執行緒功能的類。目標是我沒有任何來自外部的阻塞方法,盡管我在類中使用了具有阻塞函式的庫。我想在他們自己的執行緒中運行它們。不幸的是,我收到了記憶體故障(核心轉儲)錯誤。
在 c 11 中實作這樣的事情的最佳實踐是什么,為什么我會得到錯誤,我怎樣才能最好地提前為我想在執行緒中呼叫的函式指定記憶體?
我的課
..
class foo {
void startUp();
foo();
~foo();
std::thread foo_worker;
int retValue;
};
void foo::startUp() {
int retValue = 0;
std::thread t([this] () {
retValue = blocking_lib_func();
});
foo_worker = std::move(t);
}
foo::~foo() {
....
foo_worker.join();
}
我的主要
int main()
foo test();
test.statUp()
}
uj5u.com熱心網友回復:
與您的執行緒關聯的 lambda 正在捕獲對本地堆疊變數的參考。當startUp回傳時,執行緒將繼續運行,但 的地址retValue現在是不受限制的,包括執行緒。該執行緒將通過嘗試為該參考分配某些內容來創建未定義的行為retValue。這很可能是您描述的崩潰的根源。或者更糟的是,主執行緒上的堆疊損壞會以其他方式破壞您的程式。
解決方法很簡單。首先,retValue為您的類創建一個成員變數。雖然我們在這里,但沒有理由讓 foo_worker 成為一個指標。
class foo {
public:
void startUp();
foo();
~foo();
private:
std::thread foo_worker;
int retValue;
};
那么你的startUp代碼可以是這個。我們可以使用std::move將執行緒從本地t執行緒變數移動到類實體的成員變數中。
void foo::startUp() {
std::thread t([this] () {
retValue = blocking_lib_func(); // assign to the member variable of foo
});
foo_worker = std::move(t);
}
然后你的解構式可以呼叫 join 如下:
foo::~foo() {
....
foo_worker.join();
}
正如評論中的其他人指出的那樣,volatile沒有用。當使用適當的執行緒和鎖定語意時,它大多被棄用為關鍵字。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/382672.html
