5

我有一個屬性@property NSLock *myLock如何鎖定NSLock在一個特定的線程

我想寫兩個方法:

- (void) lock 

- (void) unlock 

這些方法鎖定和解鎖myLock分別是他們需要這樣做,而不管它們是什麼線程或隊列。例如,線程A可能調用了lock,但隊列B可能是調用unlock的那個。這兩種方法都應該適當地工作,而不報告我正試圖解鎖來自鎖定它的不同線程/隊列的鎖。另外,他們需要同步做到這一點。

回答

23

NSLock這個工作非常罕見。現在有更好的工具,特別是GCD;更晚。

正如你可能已經從the docs知道,但我會重複那些一起閱讀:

警告:NSLock類使用POSIX線程執行其鎖定行爲。向NSLock對象發送解鎖消息時,必須確保該消息是從發送初始鎖定消息的同一線程發送的。解鎖來自不同線程的鎖可能導致未定義的行爲。

如果您嘗試在不同的線程上鎖定和解鎖,那麼如果沒有死鎖就很難實現。根本的問題是,如果lock阻塞該線程,則後續的unlock無法在該線程上運行,並且不能在另一個線程上運行unlockNSLock不適用於此問題。

而不是NSLock,您可以使用dispatch_semaphore_create()實現相同的模式。這些可以安全地更新你喜歡的任何線程。您可以使用dispatch_semaphore_wait()進行鎖定,您可以使用dispatch_semaphore_signal()解鎖。也就是說,這個仍然是通常不是正確的答案。

大多數資源爭用最好使用操作隊列或分派隊列進行管理。這些提供了並行處理工作,管理資源,等待事件,實施生產者/消費者模式,以及其他幾乎所有您在過去使用NSLockNSThread所做的所有事情的絕佳方式。我強烈推薦Concurrency Programming Guide作爲介紹如何設計隊列而不是鎖定。