簡體   English   中英

C ++ 11中的線程

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM