使用GCD和代码重用:避免重入代码死锁

时间:2013-03-15 22:25:13

标签: ios multithreading grand-central-dispatch deadlock reentrancy

我正在使用GCD为类添加线程安全性。

我的类的一些公共方法由类中的其他公共方法调用。但是,这会导致重入锁定问题:如果我使用同步GCD块保护适当的公开可见方法(在某些情况下),重用意味着有时我会尝试在当前队列上运行另一个同步块,这导致僵局。

最优雅的解决方案是什么?一种显而易见的方法是拥有适当方法的内部版本,没有任何GCD块,以及具有GCD块的方法的外部公共版本包装对内部方法的调用。这对我来说不太合适。

2 个答案:

答案 0 :(得分:0)

以下是一些想法:

  1. 查看是否不能使用不可变对象。这意味着每当方法修改对象时,它实际上返回一个具有修改状态的新对象。然后块将继续使用这个新对象。这很简单,不需要特别小心,但并不总是可行。

  2. 查看您的公共方法是否不能使用带有状态的私有方法。由于每个块都带有自己的内部状态,因此您也是线程安全的。

  3. 如果您有一些示例用例,可能会产生更多想法...

答案 1 :(得分:0)

我在使用调度队列进行同步的C ++类中非常成功地使用了这样的模式:

class Foo
{
public:
    void doSomething() {
        dispatch_sync(fQueue, ^{ doSomething_sync(); });
    }

private:
    void doSomething_sync() { ... }

private:
    dispatch_queue_t fQueue;
};

此处的一般惯例是,对于课程中任何给定的_sync方法,您只能调用其他_sync方法,而不是非_sync公共方法。