私有对象的互斥锁 - 全局与属性

Posted

技术标签:

【中文标题】私有对象的互斥锁 - 全局与属性【英文标题】: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 方法中更改它。 【参考方案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 的互斥体可能应该是同一类的成员。

【讨论】:

以上是关于私有对象的互斥锁 - 全局与属性的主要内容,如果未能解决你的问题,请参考以下文章

销毁全局对象[关闭]

GIL(全局解释器锁)与互斥锁

多线程安全----同步锁(互斥锁)

07-互斥锁import threading# 定义全局变量g_num = 0# 创建全局的互斥锁lock

在 C# 中使用全局互斥锁的好模式是啥?

linux下信号量和互斥锁的区别