2012-08-24 53 views
1

如果我們需要實現一個隊列(由NSMutableArray完成),並且我們有Producer將數據添加到隊列的對象。可以有1個生產者或多個生產者。如果隊列已滿(例如,大小爲100),線程應該被「阻塞」(等待,直到隊列實際上小於100個項目)。 (從隊列中提取數據也是一樣:當數據爲空時,數據的獲取也被阻止)。在iOS上,如何在產生數據的線程上實現阻塞或「被阻塞」?

這個「阻塞」如何實現?現在,我使用的是互斥

@property (strong, atomic) NSLock *lock; 

,這樣得到的NSMutableArray的數量和項目的增加是做在一起(因爲計數可99,但添加的項目時,計數就已經是不同的)。

但是對於阻塞效應,我實際上檢查了計數,如果是100,釋放鎖和睡眠0.1秒,然後再次獲得鎖並獲得計數,並重復如上。

這是實施「阻塞」行爲的好方法嗎?似乎還有另外一種方法來獲得canAddNowLock,它只是簡單地被NSLock機制阻止,並且在刪除隊列項時,然後釋放此canAddNowLock,但由於可能有多個數據生成器和數據使用者,因此如果多個生產者是暢通無阻,或者如果多個消費者連續解鎖canAddNowLock,並且只有1個生產者被解除封鎖(實際上應該解除封鎖)。這只是一種更復雜的設計。

回答

1

使用NSCondition *條件 線程1:

[condition lock]; 
//check the queue is not full 
[condition wait];//if already full, wait 
//check again 
//put something into queue 
[condition unlock]; 

線程2:

[condition lock]; 
//check the queue is not empty 
//get something from queue 
[condition signal]; 
[condition unlock]; 
+0

用於線程1,所以'[條件等待]'和'[再次檢查]'需要在一個循環? (但是因爲'信號'喚醒了1個線程(即使多線程正在等待,所以也許這會完成這項工作......即使是第二次檢查'//再次檢查'也不需要?) –

+0

for multiple thread ,你可以使用[條件廣播]來喚醒他們所有的人,第二次檢查是爲了安全起見,你不能太小心多線程 – fvwmer

+0

所以如果要小心,不需要檢查和等待在一個循環中呢?(但是即使再次檢查,如果有錯誤,那麼即使在第二次檢查和數據添加之間,已經可能已經發生了一些不良影響已經發生在其他地方......我查閱7本頂級iOS書籍(包括2本烹飪書)的方式,其中沒有一本在索引部分有'NSCondition',但有2本官方Apple iOS指南覆蓋它) –