当前位置:  开发笔记 > 编程语言 > 正文

为什么传递对Mutex类的引用不是一个好的设计?

如何解决《为什么传递对Mutex类的引用不是一个好的设计?》经验,为你挑选了1个好方法。

从这里:我定义的Mutex类中的逻辑错误以及我在生产者消费者程序中使用它的方式 - pthreads

你将引用(!)传递给你的互斥体类的方式显然是在寻找麻烦,它无视任何类型的封装.

为什么这是个问题?我应该通过值传递然后编写复制构造函数吗?

在这种情况下,缺少封装有什么危害呢?我应该如何封装什么?

另外,为什么传递对Mutex类的引用不是一个好的设计?

传递对锁的引用是一个坏主意 - 你不"使用"锁,你只获得然后你还给它.移动它使得很难跟踪您对(关键)资源的使用.传递对互斥锁变量而不是锁定的引用可能并不是那么糟糕,但仍然会让人更难以知道程序的哪些部分可能会死锁,所以要避免它.

请用简单的语言解释一下 - 为什么传递引用是一个坏主意?



1> Curious..:

我认为这是糟糕的抽象以及糟糕的封装.a mutex通常是默认构造的,删除了复制构造函数,具有多个引用同一逻辑对象的互斥对象容易出错,即它可能导致死锁和其他竞争条件,因为程序员或读者可以认为它们是不同的实体.

此外,通过指定您正在使用的内部互斥体,您将公开线程的实现细节,从而打破Mutex类的抽象.如果你正在使用a pthread_mutex_t那么你很可能会使用内核线程(pthreads).

封装也被破坏,因为您的互斥锁不是单个封装的实体,而是分散到几个(可能是悬空的)引用中.

如果要将a封装pthread_mutex_t到类中,则可以这样做

class Mutex {
public:
    void lock(); 
    void unlock();

    // Default and move constructors are good! 
    // You can store a mutex in STL containers with these
    Mutex();
    Mutex(Mutex&&);
    ~Mutex();

    // These can lead to deadlocks!
    Mutex(const Mutex&) = delete;
    Mutex& operator= (const Mutex&) = delete;
    Mutex& operator= (Mutex&&) = delete;

private:
    pthread_mutex_t internal_mutex;
};

互斥对象应在实现文件中声明的共享范围内共享,而不是在本地声明它并在函数中作为引用传递.理想情况下,您只需将参数传递给您需要的线程构造函数.将对象中声明的对象的引用传递给与所讨论的函数相同的"级别"(在这种情况下为线程执行)通常会导致代码中的错误.如果声明互斥锁的范围不再存在会发生什么?析构函数是否mutex会使互斥体的内部实现无效?如果互斥体通过传递进入整个其他模块并且该模块启动其自己的线程并认为互斥锁永远不会阻塞,会发生什么情况,这可能导致令人讨厌的死锁.

另外一个你想使用互斥锁移动构造函数的情况是在互斥工厂模式中,如果你想创建一个新的互斥锁你会进行函数调用,该函数会返回一个互斥量,然后你将它添加到你的列表中互斥体或传递给通过某种共享数据请求它的线程(前面提到的列表对于这个共享数据是一个好主意).然而,获得这样的互斥工厂模式可能非常棘手,因为您需要锁定对公共互斥体列表的访问.尝试它应该是一件有趣的事情!

如果作者的意图是避免全局范围,那么在实现文件中将其声明为静态对象应该是足够的抽象.

推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有