簡體   English   中英

沒有正確使用NSLock,但似乎仍然有效

[英]Not using NSLock correctly, but still seems to work

我遇到線程安全問題。 我有一個隊列,當我修改內容時導致跨線程的錯誤。 我以前沒用過鎖,但我想我試試。 我為所有操作我的隊列的后備NSMutableArray的代碼添加了一個鎖。 我認為,問題在於我沒有對所有這些使用相同的鎖。 我在每個修改數組的方法中創建了一個新的NSLock實例。 我假設我應該使用一個NSLock ivar來保護陣列。 但是我的困惑來自於我添加它后它才起作用的事實。 以下是一個示例。 我假設在我創建新的NSLock的任何地方,我應該只使用一個ivar NSLock。 我認為這個代碼只是鎖定了其他隊列和反對其他隊列的隊列而不是列入隊列的隊列。 澄清會很棒。

@implmentation

...    

- (void)enqueue:(id)obj
{
  NSLock *arrayLock = [[NSLock alloc] init];
  [arrayLock lock];
   [_backingStore addObject:obj];
  [arrayLock unlock];
}

- (id)dequeue
{
  NSLock *arrayLock = [[NSLock alloc] init];
  [arrayLock lock];
  id result = [_backingStore firstObject];

  if( result )
  {
    [_backingStore removeObjectAtIndex:0];
  }

  [arrayLock unlock];
  return result;
}

...

@end

是的,您確實需要使用相同的NSLock實例來鎖定對陣列的兩次訪問。 與許多多線程錯誤一樣,由於添加附加代碼導致的時序差異,問題可能似乎已消失。 或者,它可能只是你(非)幸運,當你第二次測試時問題沒有出現。

無論它值多少,NSLock只是鎖定Objective-C中關鍵部分訪問的一種方式。 您也可以使用@synchronized() ,從代碼復雜性的角度來看,這可能更容易:

@synchronized(someSharedToken) {
    // Do your array access here
}

您還可以使用串行調度隊列來序列化對資源的訪問。 這有幾個優點,其中最重要的是能夠在不等待當前線程完成工作的情況下將工作分派給它。 將工作分配到隊列的成本也比取出鎖定要便宜。 請參閱Apple的並發編程指南的“ 創建串行調度隊列”部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM