在目标C中有一种方法可以定义一个线程安全的静态int吗?线程安全的静态变量目标c
例如,如果我有一个称为会话类,它具有:
static unsigned int session_id = 1000;
- (int) generateSessionID{
return session_id++;
}
我构建在不同的线程会话对象,每个会话对象 应该有一个唯一的ID。
在目标C中有一种方法可以定义一个线程安全的静态int吗?线程安全的静态变量目标c
例如,如果我有一个称为会话类,它具有:
static unsigned int session_id = 1000;
- (int) generateSessionID{
return session_id++;
}
我构建在不同的线程会话对象,每个会话对象 应该有一个唯一的ID。
如果你谈论的可可,还有由NSLock
和NSRecursiveLock
提供的互斥功能。
为了正确保护非原子资源,您需要这些互斥锁,以免多个线程可能试图同时更改数据(导致损坏)或使用处于半改变状态的数据(导致无效数据)。如果你不使用可可(或使依稀记得,这是近没用什么小Cocoa编程我与iMac的插曲我记得)
static NSLock session_id_lock;
static unsigned int session_id = 1000;
- (int) generateSessionID{
int new_id;
[myLock lock];
new_id = session_id++;
[myLock unlock];
return new_id;
}
:
您的代码将是这个样子,只是使用的概念,将其转换成您有任何语言或框架:
解释说,最后一点多一些:如果你有两个完全无关的事情上self
同步(比如会话ID和用户ID),他们将阻止对方尽管它没有必要这么做。我宁愿使用两个独立的互斥锁来保持较低的粒度。
当然,如果你只有一个会话ID单独的互斥体(但请参阅下面的警告),请随时使用synchronized(self)
,但我宁愿按照我的方式做,所以我不会被抓到添加其他受保护资源。
在任何情况下(这都是提到的警告),您可能会发现在self
上同步将无法充分保护静态变量,该变量将在多个对象之间共享。该互斥量应该属于数据而不是使用它的任何内容。
我来自Java世界,您可以在其中完成:static synchronized int generateID(){return sessionId ++}。这是兼容的,如果我做 - (int)generateSessionID {synchronized(self){return session_id ++;}}? – Unis 2010-10-28 02:42:12
我认为这样做可行,虽然对自己(对象)的锁定可能比我想要的更宽泛。相反,我更喜欢一个特定的互斥量,以避免不必要的互斥量延迟(请参阅我的额外奖励建议)。 – paxdiablo 2010-10-28 02:45:53
@ user489579关闭,但不希望为访问静态变量的实例方法在'self'上同步;可能会在'[self class]'上同步,或者与您正在修改的值直接关联的对象上(例如,将int包装在NSNumber中并在NSNumber上同步)。 – 2010-10-28 02:47:27
我认为你最好使用atomic operations修改session_id
。 A previous question讨论关于OS X的原子增量/减量操作,this page讨论关于OSAtomic
头文件。整数上的原子操作(这些操作很容易被硬件支持)可能比使用锁定构造要快得多。
同意。如果你所做的只是为了得到一个全局递增值而保持静态,那么使用'OSAtomicIncrement32',这将是安全的,并且不具有Cocoa或POSIX同步原语的所有开销。 – 2010-11-20 16:00:56
http://developer.apple。com/library/mac /#文档/可可/概念/多线程/ ThreadSafety/ThreadSafety.html#// apple_ref/doc/uid/10000057i-CH8-SW14 – mcfedr 2012-03-23 13:37:53
有很多选项,包括(从高级到低级)@synchronized
Objective-C指令,NSLock
,pthread_mutex_lock
和原子操作。
有关详细信息,请阅读Threading Programming Guide的“同步”部分。
4年后的回应目前在iOS8。 :O) 对我最好的方法是使用一个单独的类,如下所示:
(yourFile.h)
#import <Foundation/Foundation.h>
@interface singletonSessionId : NSObject
+ (singletonMsgNbr*)sharedSingleton;
- (void)generateSessionId;
@property NSInteger value;
@end
================= ==================================== (yourFile.m)
#import "singletonSessionId.h"
@implementation singletonSessionId
@synthesize value = _value;
+ (singletonMsgNbr*)sharedSingleton {
static singletonSessionId *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[singletonSessionId alloc]init];
instance.value = 1000;
});
return instance;
}
- (void)generateSessionId {
_value += 1;
}
@end
你只需要为每个新的Id值调用方法'generateSessionId'。 使用这个类来生成你的会话Ids应该足够我想。
希望它能帮助这篇文章的读者。 :o)
@ondermerol:的确如此,它就是这样做的=>'您只需要为每个新的Id值调用方法'generateSessionId'。 – 2015-06-15 08:12:50
对不起,迟到的答案,它的作品像一个魅力,我只犯了一个错误。 – ondermerol 2015-06-22 14:02:24
@ XLE_22:这个线程安全吗?假设thread1调用generateSessionID,那么在thread1有机会检索值之前,thread2调用generateSessionID?他们都不会使用相同的ID吗?如果他们都同时调用这个方法,那么由于没有使用同步工具,是不是有可能导致内存损坏? – jk7 2016-01-08 19:07:09
您需要使用某种锁定语义。问题是你想要操作是原子的。但请记住,“++”不是原子的,它只是一些操作。 – BobbyShaftoe 2010-10-28 02:25:12
是可能的,然后用synchronized(self){return session_id ++}包围我的return session_id ++。但是我不确定这是否会锁定类或它自己的对象。 – Unis 2010-10-28 02:32:09
按照写法,它会锁定实例,而不是类(不是你想要的)。也许“'@synchronized([self class])'”? – 2010-10-28 02:45:33