我在寫一個Objective-C類,我想要線程安全。要做到這一點,我使用pthreads和pthread_rwlock
(使用@synchronized
是矯枉過正,我想了解更多關於pthreads)。該鎖定在指定爲init
方法的對象中,並在dealloc
中銷燬。我有三種操作鎖定的方法; readLock
,writeLock
,unlock
。這三個方法只是簡單地調用相關的pthread函數,目前沒有其他的東西。如何確定線程是否有鎖?
下面是的對象的方法,兩者都需要一個writeLock二:
-(void)addValue:(const void *)buffer
{
[self writeLock];
NSUInteger lastIndex = self.lastIndex;
[self setValue:buffer atIndex:(lastIndex == NSNotFound) ? 0 : lastIndex+1];
[self unlock];
}
-(void)setValue:(const void *)buffer atIndex:(NSUInteger)index
{
[self writeLock];
//do work here
[self unlock];
}
setAddValue:
調用將首先獲得寫入鎖定,然後調用setValue:atIndex:
這也將試圖獲得一個寫鎖。該文檔指出,發生這種情況時行爲是不確定的。因此,如何在嘗試獲取鎖之前檢查線程是否有鎖? (我可以確保臨界區不會觸發另一個鎖請求,但這意味着代碼重複,並且我想讓我的代碼幹掉)。
該信息稍微正確。 'EDEADLK'錯誤只針對'pthread_rwlock_(rd | wr)鎖定'指定,而不是trylock函數,在這種情況下它將返回'EBUSY',並且不區分鎖定是由調用線程還是其他線程持有。此外,由同一個線程保持的鎖只有在寫入鎖定時才能檢測到。由於可以有無限數量的閱讀器,所以持有鎖的閱讀器的身份不能被檢查。然而,在OP的情況下,它看起來像一個雙重寫鎖是需要避免的問題,所以它可能是好的。 – 2011-04-23 21:25:05
此外,'EDEADLK'錯誤只是一個「可能」,而不是「應該」,即不需要執行檢測和報告 – 2011-04-23 21:26:45
在進一步的考慮中,我認爲您的解決方案不可行。我已經發布了一個替代方案作爲答案。 – 2011-04-23 21:32:44