关键部分或互斥体是否应该是成员变量或何时应该是?

时间:2017-04-27 14:59:02

标签: c++ multithreading

我见过代码,其中mutex或critical section被声明为类的成员变量,以使其线程安全,如下所示。

class ThreadSafeClass
{
public:
    ThreadSafeClass() { x = new int; }
    ~ThreadSafeClass() {};

    void reallocate()
    {
        std::lock_guard<std::mutex> lock(m);

        delete x;
        x = new int;
    }

    int * x;
    std::mutex m;
};

但是,如果多个线程共享相同的对象,那么它是否只能 ?换句话说,如果每个线程都在创建自己的这个类的实例,那么它们将是非常独立的,它的成员变量永远不会相互冲突,在这种情况下甚至不需要同步!?

在我看来,当多个线程共享相同的对象时,将互斥锁定义为成员变量确实会减少与事件的同步。如果每个线程都有自己的类副本(例如,如果类要访问其他全局对象),那么它并不能真正使类更安全。这是正确的评估吗?

1 个答案:

答案 0 :(得分:2)

如果您可以保证任何给定对象只能被一个线程访问,那么互斥是一种不必要的开销。但是,必须在班级合同中详细记录,以防止滥用。

PS:newdelete有自己的同步机制,因此即使没有锁定,也会产生争用。

编辑:你保持线程彼此独立的越多越好(因为它消除了对锁的需要)。但是,如果您的类将使用共享资源(例如数据库,文件,套接字,内存等),那么拥有每个线程的实例几乎没有优势,因此您可以在线程之间共享一个对象。通过让不同的线程使用不同的内存位置或资源来实现真正的独立性。

如果你的锁会有很长的等待时间,那么让一个实例在自己的线程中运行并从同步队列中获取“作业”可能是个好主意。