在我的应用程序中,网络请求密钥交换由C ++编写,并在我的xcode项目中通过库链接。它不是线程安全的,这意味着如果两个线程同时加密或解密,则会发生意外行为。我总是以这种方式调用它。
TnKeyChangeInstance::instance()->encrypt(inStr, outStr);
您知道,@synchronized
仅适用于NSObject
类型对象,如何为C ++代码添加锁定,如上面的单例?有什么想法吗?
答案 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()
调用。如果单例实现不是过于复杂,那么这种方法可能是最好的,如果你在从你的实现派生的类中进行线程安全的更改,那么这种方法会更好。