编码风格:锁定/解锁内部还是外部?

时间:2010-09-10 19:34:44

标签: coding-style locking pthreads objective-c++

另一个可能无聊的问题:

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

e.g。没有特别的语言...

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

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

OR

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

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

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

帮助?

谢谢,

3 个答案:

答案 0 :(得分:3)

被叫方,而不是来电者应该进行锁定。被调用者是唯一知道需要同步的人,也是唯一能够确保同步的人。如果你将锁定留给呼叫者,你会做三件坏事:

  1. 您增加了功能/类别用户的负担,增加了设计粘度。
  2. 您可以让呼叫者无需锁定即可更新共享状态。
  3. 如果不同的函数以不同的顺序执行多个锁定,则会引入死锁的可能性。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我们了解到,如果您需要一次执行多个相互关联的细化操作,或者需要参照内部结构进行操作,则外部锁定会带来很多好处-只要您需要安全进行一系列工作,就可以持有一个锁来自其他线程。

一个例子:一个管理项目列表的容器可能想提供一个api,以获取对一个项目的可变引用。如果没有外部锁定,则函数调用结束后,另一个线程可能会锁定和变异数据。一个可行的解决方案是返回一个项目的副本,但这效率低下。

也就是说,在某些情况下,内部锁定可以使用更简洁的api,前提是您可以确定将锁的保留时间不超过一个函数调用的时间。