在目標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