簡體   English   中英

使用互斥鎖鎖定對結構的訪問

[英]Locking access to struct with mutex

我有一個包含兩個元素的結構。

struct MyStruct {
  int first_element_;
  std::string second_element_;
}

該結構在線程之間共享,因此需要鎖定。 我的用例需要鎖定對整個結構的訪問,而不僅僅是特定成員,例如:

  // start of Thread 1's routine
  <Thread 1 "locks" struct>
  <Thread 1 gets first_element_>
  <Thread 1 sets second_elements_>
  <Thread 2 wants to access struct -> blocks>
  <Thread 1 sets first_element_>
  // end of Thread 1's routine
  <Thread 1 releases lock>
  <Thread 2 reads/sets ....>

這樣做最優雅的方式是什么?

編輯:為了澄清,基本上這個問題是關於如何強制使用此結構的任何線程在其例程開始時鎖定互斥鎖(存儲在任何地方)並在其結束時解鎖互斥鎖。

EDIT2:我當前的(丑陋的)解決方案是在 MyStruct 內有一個互斥鎖,並在每個使用 MyStruct 的線程例程開始時鎖定該互斥鎖。 但是,如果一個線程“忘記”鎖定該互斥鎖,我就會遇到同步問題。

您可以擁有一個類而不是結構體,並為first_element_second_element_實現 getter 和 setter。 除了這些類成員之外,您還需要一個std::mutex類型的成員。

最終,您的類可能如下所示:

class Foo {
public:
    // ...

    int get_first() const noexcept {
        std::lock_guard<std::mutex> guard(my_mutex_);
        return first_element_;
    }

    std::string get_second() const noexcept {
        std::lock_guard<std::mutex> guard(my_mutex_);
        return second_element_;
    }

private:
    int first_element_;
    std::string second_element_;
    std::mutex my_mutex_;
};

注意,getter 正在返回數據成員的副本。 如果你想返回引用(比如std::string const& get_second() const noexcept )那么你需要小心,因為獲取對第二個元素的引用的代碼沒有鎖保護,在這種情況下可能會出現競爭條件.

在任何情況下,您的方法是使用std::lock_guard s 和std::mutex es 圍繞可以由多個線程使用的代碼。

你可以實現這樣的東西,將鎖與數據結合起來:

class Wrapper
{
public:
   Wrapper(MyStruct& value, std::mutex& mutex)
   :value(value), lock(mutex) {}

   MyStruct& value;
private:
   std::unique_lock<std::mutex> lock;
};

class Container
{
public:
   Wrapper get()
   {
      return Wrapper(value, mutex);
    }
private:
   MyStruct value;
   std::mutex mutex;
};

互斥鎖在您調用get時被鎖定,並且在Wrapper超出范圍時自動解鎖。

暫無
暫無

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

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