從atomic關鍵字說到多執行緒安全(內含ios給**加鎖方法總結)
自旋鎖和互斥鎖區別
**屬性關鍵字
ios屬性關鍵字
nonatomic
關於執行緒安全
讀寫許可權
引用計數
unsafe_unretained:
weak:
copy:
atomic是預設的原子操作關鍵字,atomic也就代表其具有原子性
atomic 屬性關鍵字會給該 property 的 getter和setter方法加鎖,但不能保證執行緒一定安全並且會帶來更多損耗。
互斥鎖(mutexlock):
最常使用於執行緒同步的鎖;標記用來保證在任一時刻,只能有乙個執行緒訪問該物件,同一執行緒多次加鎖操作會造成死鎖;臨界區和互斥量都可用來實現此鎖,通常情況下鎖操作失敗會將該執行緒睡眠等待鎖釋放時被喚醒。
在多工作業系統中,同時執行的多個任務可能都需要使用同一種資源。互斥鎖是一種簡單的加鎖的方法來控制對共享資源的訪問,互斥鎖只有兩種狀態,即上鎖( lock )和解鎖( unlock )。
原子性:把乙個互斥量鎖定為乙個原子操作,這意味著作業系統(或pthread函式庫)保證了如果乙個執行緒鎖定了乙個互斥量,沒有其他執行緒在同一時間可以成功鎖定這個互斥量;
唯一性:如果乙個執行緒鎖定了乙個互斥量,在它解除鎖定之前,沒有其他執行緒可以鎖定這個互斥量;
非繁忙等待:如果乙個執行緒已經鎖定了乙個互斥量,第二個執行緒又試圖去鎖定這個互斥量,則第二個執行緒將被掛起(不占用任何cpu資源),直到第乙個執行緒解除對這個互斥量的鎖定為止,第二個執行緒則被喚醒並繼續執行,同時鎖定這個互斥量。
自旋鎖(spinlock):
同樣用來標記只能有乙個執行緒訪問該物件,在同一執行緒多次加鎖操作會造成死鎖;使用硬體提供的swap指令或test_and_set指令實現;同互斥鎖不同的是在鎖操作需要等待的時候並不是睡眠等待喚醒,而是迴圈檢測保持者已經釋放了鎖,
互斥量阻塞後休眠讓出cpu,而自旋鎖阻塞後不會讓出cpu,會一直忙等待,直到得到鎖。這樣做的好處是節省了執行緒從睡眠狀態到喚醒之間核心會產生的消耗,在加鎖時間短暫的環境下這點會提高很大效率。適用於鎖的持有時間比較短。
而nonatomic就是非原子性的,不會給setter,getter方法加鎖
我們一般把屬性設定為這個。
很多文章談到atomic和nonatomic的區別時,都說atomic是執行緒安全,其實這個說法是不準確的。 atomic只是對屬性的getter/setter方法進行了加鎖操作,這種安全僅僅是set/get的讀寫安全,並非真正意義上的執行緒安全,因為執行緒安全還有讀寫之外的其他操作(比如:如果當乙個執行緒正在get或set時,又有另乙個執行緒同時在進行release操作,可能會直接crash)。
static inline void reallysetproperty(id self, sel _cmd, id newvalue, ptrdiff_t offset, bool atomic, bool copy, bool mutablecopy)
id oldvalue;
id *slot = (id*) ((char*)self + offset);
if (copy) else if (mutablecopy) else
if (!atomic) else
objc_release(oldvalue);
}
核心**為自旋鎖在讀寫操作時鎖定
spinlock_t& slotlock = propertylocks[slot];
slotlock.lock();
oldvalue = *slot;
*slot = newvalue;
slotlock.unlock();
讀寫許可權這一塊很好理解,就是乙個readwrite以及乙個readonly
一般情況下,retain用在mrc情況下,被retain修飾的物件,引用計數retaincount加1。
retain只能修飾oc物件,不能修飾非oc物件,比如說corefoundation物件就是c語言框架,它沒有引用計數,也不能用retain進行修飾。
retain一般用來修飾非nsstring 的nsobject類和其子類。
strong可以說是arc下retain的表現形式
修飾基本資料型別:int、bool
修飾物件型別時,不改變引用計數
會產生懸垂指標/野指標(assign修飾的物件在被釋放之後,指標仍舊指向之前的記憶體位址,可能會因為懸垂指標的原因導致記憶體洩漏、程式異常)
因為 assign 修飾的物件,在釋放之後,指標的位址還是存在的,也就是說指標並沒有被置為nil,造成野指標。訪問野指標,會導致程式 crash。
因為基本資料型別是分配在棧上,棧的記憶體會由系統自己自動處理**,不會造成野指標。
assign和retain對應了arc下的weak和strong。
strong 和copy。
弱引用,多用於物件型別,引用的物件被釋放後,對他沒什麼影響,而且他不是arc所管理的物件
不改變被修飾物件的引用計數。(解決迴圈引用)
所指向的物件被釋放之後會自動置為nil(為什麼會被置為nil了呢,記憶體關聯章節有答案)
weak比較常用的地方就是delegate屬性的設定。
其setter方法,與retain處理流程一樣,先舊值release,再copy出新的物件。
在mrc和arc下都可以使用。
copy可以用於對不可變容易的屬性修飾中,主要是nsarray /nsdictionary/nsstring, 也可以用來修飾block。
使用了copy關鍵字的屬性,setter方法會呼叫copywithzone:方法,生成物件的副本,可是如果是可變物件,用了copy關鍵字,那麼它的副本就是不可變的,也就無法呼叫修改物件的方法。
例如nsmutablearray使用了copy關鍵字修飾,它就無法呼叫addobject等方法,會報出無法找到選擇子的錯誤。
iosios屬性關鍵字
atomic 原子操作 原子性是指事務的乙個完整操作,操作成功就提交,反之就回滾.原子操作就是指具有原子性的操作 在objective c 屬性設定裡面 預設的就是atomic 意思就是 setter getter函式是乙個原子操作,如果多執行緒同時呼叫setter時,不會出現某乙個執行緒執行完se...
IOS 屬性關鍵字
ios 5之後便支援arc了,在arc的情況下物件引用分為 strong強引用 乙個物件如果有乙個及以上的強引用指向它,那麼他將不會釋放 weak弱引用 乙個物件如果只有弱應用指向它,那麼它將被釋放掉 注 兩個物件若相互保留對方的強引用,那麼會照成記憶體洩漏。其他 copy 物件的複製,複製之後得到...
iOS屬性關鍵字
常用的屬性關鍵字 assign,weak,unsafe unretained,strong,retain copy,readonly,readwrite nonatomic,natomic及 weak,block synthesize 和 dynamic,只有準確的理解了他們的原理,用起來才能得心應...