簡體   English   中英

在類中正確使用互斥鎖,lock_guard和unique_lock

[英]Using mutex, lock_guard, unique_lock properly in a class

我正在嘗試更好地理解與類一起使用時的std::mutexstd::lock_guardstd::unique_lock

對於初學者,我有點了解lock_guardunique_lock之間的區別:我知道lock_guard僅在構造上鎖定互斥鎖,這是在類成員函數中使用它的首選用法:

class Foo {
    std::mutex myMutex;

public:
    void someFunc() {
        std::lock_guard<std::mutex> guard( myMutex );

        // code
    }
};

像上面一樣,具有類成員myMutex的lock_guard將在函數Foo::someFunc()的作用域的開始處鎖定,然后在代碼離開作用域之后由於lock_guardmutex的析構函數而被解鎖。

我也知道unique_lock允許您多次鎖定和解鎖互斥鎖。

我的問題是關於一個課堂設計的地方。 如果我希望互斥鎖被鎖定在該類的構造函數中,那么在constructor超出范圍時不要使其解鎖,而是在調用該類的析構函數時使其解鎖...

class Foo {
    std::mutex myMutex;
public:
    Foo() {
        // lock mutex here;
    }

    ~Foo() {
        // unlock mutex here;
    }
};

可以實現以上目標嗎? 如果可以,怎么辦?

在上面的最后一個示例中,我不確定的是:如果在類的構造函數中使用了lock_guard; 在構造函數離開作用域之后,或者當類的對象超出作用域時調用類的析構函數時,它將超出作用域嗎? 我想嘗試模仿所示第二個示例的預期行為。

發布此問題后:我做了一些研究,並做了一些試驗和錯誤。 因此,我選擇了不同的實現和解決方案。

最終我沒有使用最初的建議,而是使用了std::shared_mutexstd:shared_lock

因此,在類的標題中,我沒有保存或存儲任何mutex 現在在我班的cpp文件中。 我正在使用靜態全局shared_mutex

所以我的課現在看起來像這樣:

Foo.cpp

#include "Foo.h"

#include <mutex>

std::mutex g_mutex;

Foo::Foo() {
    // code not locked

    {   // scope of guard
        std::lock_guard<std::mutex> lock( g_mutex );
        // code to lock
    } // end scope destroy guard unlock mutex

    // other class code
}

Foo::someFunc() {
    // Code to lock
    std::lock_guard<std::mutex> lock( g_mutex );
}

我發現了為什么它對我來說無法正常工作。 在我的類的構造函數中,它是從其父類或基類中調用一個函數。 然后,父類或基類正在調用該類的靜態成員,而該類的靜態成員函數也在同一互斥鎖上使用lock_guard。

我發現問題后; 我有兩個選擇。 我可以使用2個獨立的互斥體,一個專門用於構造函數,一個專門用於靜態方法。 經過一番思考,如果我使用2,我算好了,而且我阻塞了整個構造函數,直到類實例被銷毀為止,當前的鎖和互斥才不會超出范圍。 但是,類的壽命幾乎是應用程序的整個壽命。 然后,如果我在static方法中使用了另一個互斥鎖和鎖保護,那么將另一個lock_guard包裹在現有的那個上將是多余的。 因此,我得出的結論是,我需要為需要被互斥鎖阻止的代碼創建一個有范圍的塊{ } ,以便可以在本節超出范圍后將其解鎖,然后構造函數可以自由調用static方法,並且可以重用與現在免費的相同的互斥量。 該類現在可以正常工作,並且在不應該發生的情況下不會崩潰也不會引發異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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