【问题标题】:Mutex for private object - global vs attribute私有对象的互斥锁 - 全局与属性
【发布时间】:2020-01-31 20:19:01
【问题描述】:

我有一个可以通知对象的类处理器。 通知对象最终会在单独的线程中处理。

由于队列在不同线程之间共享,因此需要一个互斥体q_mutex 来防止错误行为。

class Processor {
    std::queue<int> q;
    void q_processing_thread();    // while true loop - uses the mutex
public:
    void notify(int);  // pushes int to q - uses the mutex
    bool isEmpty() const;     // checks if the queue is empty  - uses the mutex
};

问题:

互斥锁应该是处理器的属性还是全局变量?

从概念上来说,

  • isEmpty 应该是 const 因为它不应该改变对象。然而,这阻止了它 锁定互斥锁。
  • 互斥体在类之外没有意义,因为队列是处理器的私有属性。

【问题讨论】:

  • 制作互斥锁mutable。这允许您在 const 方法中更改它。

标签: c++ multithreading oop mutex


【解决方案1】:

互斥锁应该是类的一部分。

您可以将其指定为 mutable 以使其在 const 方法中可用。

Class Processor {
    std::queue<int> q;
    mutable std::mutex q_mutex;
    . . .
}

【讨论】:

    【解决方案2】:

    全局变量通常不受欢迎。

    由于 C++ 没有拥有互斥体,因此最好将其作为成员属性

    即使你的 this 是 const,也可以改变它

    class Processor {
        std::queue<int> q;
        mutable std::mutex mtx;
        void q_processing_thread();    // while true loop - uses the mutex
    public:
        void notify(int);  // pushes int to q - uses the mutex
        bool isEmpty() const;     // checks if the queue is empty  - uses the mutex
    };
    

    在需要互斥锁时立即锁定,最好通过 std::lock_guard 或 scoped_lock。

    不要让它锁定超过必要的时间,因为这会导致性能问题

    【讨论】:

      【解决方案3】:

      互斥锁的声明范围和范围应与其保护的数据相同。您的示例中唯一的数据是成员变量q。因此,假设您想要保护q,那么旨在保护q 的互斥体可能应该是同一类的成员。

      【讨论】:

        猜你喜欢
        • 2012-06-05
        • 2014-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多