gpt4 book ai didi

c++ - 我是否需要在返回容器拷贝的函数上加锁?

转载 作者:太空狗 更新时间:2023-10-29 19:59:34 25 4
gpt4 key购买 nike

class Manager {
public:

list<Employee> getEmployees() {
// Do I need to lock here?
return emps_;
}
void addEmp(Employee emp); //Here I have lock
private:
list<Employee> emps_;
};

实例 Manager 在多个线程之间共享。我需要给 getEmployees 成员函数加锁吗?

我很确定我需要一个锁,因为完整列表已被复制,因此在此期间(直到复制完成)进行的任何修改都可能会中断复制操作。

我问这个是因为我很少有人认为不需要锁定。

编辑:

既然现在很清楚需要锁定,我的问题是如何以最小的开销做到这一点。通过执行以下解决方案,您可以复制列表两次。:

list<Employee> getEmployees() {
pthread_mutex_lock( &mutex1 );
list<Emp> tmp = emps_; //Copy 1
pthread_mutex_unlock( &mutex1 );
return tmp;//Copy 2
}

最佳答案

复制了整个列表,但复制的源可能正在修改中。 stdlib 容器支持完全并发的解锁读取访问。另一方面写...

如果您打算在可能制作拷贝时写入此列表,则需要将其锁定。 SWMR(单写入多读取器)锁非常适合这个,顺便说一句,特别是如果您有几十个甚至数百个线程需要制作拷贝,而只需要偶尔写入。即便如此,writer-request 的饥饿是一个真正需要通过实现锁定类来解决的问题,但不是针对您在此处提出的问题的范围(没有双关语意)。

关于您的更新,我是范围释放锁的忠实拥护者(在适当的时候),在您的情况下也是如此。 IE。一个作用域对象包装器,围绕您的互斥锁,在进入时锁定它,并在作用域退出时解锁它。

我很确定 boost::人有这样的东西很容易访问,就此而言,C++11 也可能(由于工作安排,我还没有尝试过;没有停机时间呃)。但是你想要这样的东西:

list<Employee> getEmployees() 
{
scope_lock latch(&mtx);
return emps_;
}

上面的 scope_lock 只是一个简单的类,它在构建时锁定互斥锁,并在销毁时解锁它。这可以防止在您的复制构造中抛出的异常不会永久挂起您的互斥体的可能性。将其视为利用自动销毁来解锁互斥量。 RAII为了胜利。

我希望这是有道理的。对于像这样的小 get'ers 这样的东西是理想的。同样,包括 boost 在内的许多工具包都可能内置了这样的东西,如果任何 boost 人阅读了这篇文章,请牛仔起来并提供指导。上面的例子是你所能得到的最简单的作用域锁。

最后,对于 SWMR,逻辑完全相同。唯一的区别是锁将采用一个额外的参数来判断您是在请求读还是写访问权限。

关于c++ - 我是否需要在返回容器拷贝的函数上加锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12579538/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com