4

另一个可能是愚蠢的风格问题:

并发应该如何锁定?执行者或调用者应该负责锁定线程吗?

例如,没有特定的语言...

Caller::callAnotherThread() {
    _executor.method();
}

Executor::method() {
    _lock();
    doSomething();
    _unlock();
}

或者

Caller::callAnotherThread() {
    _executor.lock()
    _executor.method();
    _executor.unlock()
}

Executor::method() {
    doSomething();
}

我对线程和锁定知之甚少,所以我想确保代码是健壮的。第二种方法允许线程不安全调用......从技术上讲,您可以在不执行任何锁定的情况下调用 _executor.method()。

帮助?

谢谢,

4

3 回答 3

5

被调用者,而不是调用者应该进行锁定。被调用者是唯一知道什么需要同步并且唯一可以确保同步的人。如果你把锁定留给调用者,你会做三件坏事:

  1. 您增加了函数/类用户的负担,增加了设计粘性。
  2. 您可以让调用者在不获取锁的情况下更新共享状态。
  3. 如果不同的函数以不同的顺序获取多个锁,您就会引入死锁的可能性。
于 2010-09-10T19:42:53.563 回答
1

如果您在内部使用锁,则必须在手册文档中注明。否则你的代码会成为并行执行的瓶颈,用户很难知道真相。

于 2011-06-29T07:48:44.507 回答
1

我们了解到,如果您需要一次执行多个相互关联的细粒度操作,或者使用对内部结构的引用,则外部锁定具有优势 - 只要您需要您的工作集不受其他线程的影响,您就可以持有锁.

一个例子:一个管理项目列表的容器可能想要提供一个 api 来获取对一个项目的可变引用。如果没有外部锁定,一旦函数调用完成,另一个线程可能会锁定和改变数据。一个合理的解决方案是返回一个项目的副本,但这是低效的。

话虽如此,在某些情况下,内部锁定可以有一个更干净的 api,前提是您可以确定您不希望保留一个锁超过​​一个函数调用。

于 2019-08-06T16:08:56.220 回答