Obj-C如何在多线程环境中为C ++ singletion添加锁?

时间:2014-01-07 13:14:47

标签: ios multithreading locking

在我的应用程序中,网络请求密钥交换由C ++编写,并在我的xcode项目中通过库链接。它不是线程安全的,这意味着如果两个线程同时加密或解密,则会发生意外行为。我总是以这种方式调用它。

TnKeyChangeInstance::instance()->encrypt(inStr, outStr);

您知道,@synchronized仅适用于NSObject类型对象,如何为C ++代码添加锁定,如上面的单例?有什么想法吗?

1 个答案:

答案 0 :(得分:0)

您可以使用NSRecursiveLock

@interface MyClassUsingTnKeyChangeInstance : ... { 
  NSRecursiveLock *lock;
}
@end

@implementation MySafeMutableArray


<instantiate the lock in your init method>

- (void)lockedOp:(id)obj {
   [self.lock lock];
   <access singleton>
   [self.lock unlock];
}

@end

这种方法要求您通过MyClassUsingTnKeyChangeInstance专门访问单例(这是一个类似于@synchronized提出的约束的约束)。如果您需要以线程安全的方式访问单例,则需要将锁置于其他位置,并确保每次访问时都锁定/解锁。

另一种方法是完全消除死锁的可能性,它使用GCD串行队列来序列化对单例的所有访问。在这种情况下,您将为单例类创建一个包装器,然后调用它的每个方法:

- (void)serializeOp:(id)obj {
    dispatch_sync(self.serialQueue, ^{ <access singleton> });
}

最后一种方法是修改单例C ++实现并向其添加std::mutex::lock以使其具有线程安全性。在这种情况下,您将修改所有单例方法以向其添加mutex.lock()/mutex.unlock()调用。如果单例实现不是过于复杂,那么这种方法可能是最好的,如果你在从你的实现派生的类中进行线程安全的更改,那么这种方法会更好。