2010-09-22 78 views
2

比方說,我有2個線程,一個是主線程,另一個是輔助線程。主線程被使用得最多,但有時(很少)我想讓輔助線程根據主線程的調用做一些工作。大多數時候輔助線程應該睡覺。現在經過一番搜索,我明白了這樣做的方法是使用runLoops。所以我試圖閱讀蘋果的文檔(http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW5NSRunLoops in Cocoa?

但它看起來很複雜,我在那裏有一些困難。有沒有一種優雅而簡單的方式來實現我所描述的?任何類似的runLoop代碼示例,我可以運行和玩?

感謝

+0

這是一個很好的問題 - 我過去使用過RunLoops,但說實話,我有時只是因爲我沒有完全理解發生了什麼而只是剪掉了''代碼片段。一個簡單的例子將是一個很好的起點。 – Echelon 2010-09-22 11:44:27

回答

2

Matt Gallagher有一篇很好的博客文章,將輔助線程方法與其他獲取後臺工作的方式進行比較。

http://cocoawithlove.com/2010/09/overhead-of-spawning-threads.html

在你的情況,你不必與線程創建開銷有關。但是Matt的代碼示例可能會提供一些有關管理輔助線程runloop的信息。所有這一切說,我會去約書亞的建議,只是使用NSOperationQueue和NSOperation做後臺工作。如果工作可以封裝在NSInvocation中,則可以使用NSInvocationOperation並避免使用NSOperation子類。

+0

我在代碼中看到了一些RunLoops! :)我一定會嘗試一下。 – Alex1987 2010-09-22 18:38:44

4

這聽起來像是剛之類的事情NSOperation/NSOperationQueue被造的。如果你只有偶爾的「工作單元」,爲什麼不讓他們成爲一個操作,然後監控它的完成並相應地更新你的UI?

+0

好吧,我測試了你的建議,並不適合我的情況。 「幫助程序」線程每1秒獲取一個任務,因此在這種情況下,這意味着每秒創建一個新的NSOperation並將其添加到隊列中。 – Alex1987 2010-09-22 18:36:23

+0

究竟如何不適合?如果你指的是性能,你究竟是如何測試它的? NSOperation是非常輕量級的,隊列可以保持懸空狀態(並且在空時不會「旋轉」)。 – 2010-09-22 19:04:20

+0

那麼,我實際上正在試圖在iPhone上流式傳輸視頻。我這樣做的方式基本上是使用主線程從遠程服務器下載數據,並使用「幫助程序」線程讀取數據並將其傳遞給播放器。現在一切都是用一個線程完成的,但我想更多地改進它。所以我測試了你的建議,併爲每個「讀」添加了一個新的NSOperation,並且性能大幅下降。 – Alex1987 2010-09-22 19:13:17

4

每個線程都有一個運行循環。

每個運行循環都有一系列需要完成的事情。這些東西在運行循環中被認爲是「預定的」,儘管不是所有的都預定了特定的日期和時間:

  • 定時器是。
  • 來源不是。他們通常會等待敲入Mach內核端口或文件描述符的內容。

運行循環運行時,它通常不運行 - 即線程正在休眠,不消耗任何CPU週期。 (如果你對它進行了抽樣,你會發現這個進程似乎陷入了​​這是一個「等待發生的事情」的系統調用)。內核喚醒線程(從而從​​返回)當發生線程運行循環需要照顧的事情時。

完全按照您所描述的方式執行run loop source。您可以在輔助線程的運行循環中安排源代碼,通過工作實現它,並在需要完成工作時從主線程發出信號。

但是,NSOperation幾乎肯定是一個更好的解決方案,因爲它是專爲您所描述的情況設計的:需要連續完成的離散工作單元,每次最多N個(您選擇並至少1個) 。

請注意,NSOperationQueue重用線程,所以它不一定會爲每個操作創建一個新的線程。事實上,不這樣做是關鍵的一部分:它會懶惰地創建線程,並使用它已有的任何沒有做任何事情的線程。