[英]Threads in C++11
我正在將C ++技能更新為C ++ 11。 我要掌握線程,始終是一個問題區域。 考慮以下測試代碼:
// threaded.h
class MyThreadedClass
{
public:
MyThreadClass();
bool StartThread();
bool IsThreadDone();
inline void WorkThread();
private:
std::thread* workThread;
atomic<bool> threadDone;
}
// threaded.cpp
MyThreadedClass::MyThreadedClass() {
workThread = nullptr;
threadDone.store(true);
}
bool MyThreadedClass::StartThread() {
if (!threadDone.load()) { return false; }
threadDone.store(false);
workThread = new std::thread(&MyThreadedClass:WorkThread, this);
workThread->detach();
return true;
}
bool MyThreadedClass:IsThreadDone() {
return threadDone.load();
}
inline void MyThreadedClass::WorkThread() {
while (some_condition) { /*Do work*/ }
threadDone.store(true);
}
// main.cpp
int main() {
MyThreadedClass testInstance;
testInstance.StartThread();
for (int x = 0; x < 10; x++) {
do {
// This is sometimes true:
if (testInstance.StartThread()) { return 1;}
} while (!testInstance.IsThreadDone())
}
return 0;
}
我想看看這種代碼的最壞情況,因此我在等待線程終止的同時不斷地敲打它。 有時會觸發main中的故障情況。 與許多線程問題一樣,它也不是一致的,因此不容易調試。
使用threadDone變量是因為我以實際代碼訪問文件,並且不希望多個線程訪問同一文件。
歡迎了解我所缺少的內容或歡迎使用C ++ 11習慣用法重新設計的方法。
我了解的有關C ++ 11並發性的最佳參考書/學習書是:Anthony Williams撰寫的《 C ++並發性實踐:實用多線程》 。
使用std :: mutex而不是std :: atomic ,實現非常簡單。
class MyThreadedClass
{
std::mutex _mutex;
std::unique_ptr<std::thread> _thread;
bool _done{false};
public:
MyThreadClass() = default;
bool StartThread()
{
std::lock_guard<std::mutex> lock(_mutex);
if (_thread || _done) return false;
_thread = std::make_unique<std::thread>(&MyThreadedClass, this);
return true;
}
bool IsThreadDone()
{
std::lock_guard<std::mutex> lock(_mutex);
return _done;
}
void WorkThread()
{
// do some work
std::lock_guard<std::mutex> lock(_mutex);
_done = true;
}
}
您的main()
函數中有一個競爭條件(盡管不是“數據競爭”),我在下面對此進行了轉錄,內聯和簡化:
void MyThreadedClass::WorkThread() {
threadDone.store(true);
}
int main() {
MyThreadedClass testInstance;
testInstance.threadDone.store(false);
new std::thread(&MyThreadedClass::WorkThread, &testInstance)->detach();
// This sometimes fails:
assert(!testInstance.threadDone.load());
return 0;
}
如果WorkThread恰好在再次調度主線程之前運行完成,則該斷言將失敗。 由於標准不限制調度,因此如果需要工作線程等待,則需要編寫一些代碼來阻塞。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.