2014-04-29 73 views
2

我正在開發一個通過USB串行將數據傳輸到硬件設備的OSX應用程序。硬件有一個小的串行緩衝區,以可變速率排空並且應該始終保持非空。在OSX上創建實時線程

我們在自己的NSThread中有一個寫循環,用於檢查硬件緩衝區是否已滿,如果沒有,則直到它寫入數據。大多數循環迭代不會寫入任何內容,也幾乎不需要時間,但偶爾會花費幾毫秒(與CACurrentMediaTime一起計時)。線程在每次迭代後睡眠100ns。 (我知道睡眠時間似乎非常短,但如果我們碰到它,硬件開始變得數據匱乏。)

這很適合大多數情況。但是,如果主線程或其他應用程序開始執行某些處理器密集型操作,寫入線程變慢並且無法足夠快地傳輸數據以防止設備的隊列清空。

因此,我們希望使串行寫入線程實時。我通過Mach API讀取了要求實時調度的the Apple docs,然後嘗試修改Chromium source中的SetPriorityRealtimeAudio(mach_port_t mach_thread_id)中的代碼片段。

但是,這是行不通的 - 應用程序保持一樣容易串行通信速度的下降。有任何想法嗎?我不確定是否需要更改寫入線程的行爲,或者如果我傳遞了錯誤的線程策略參數,或兩者都有。我嘗試了各種週期/計算/約束值,並強制執行更一致的佔空比(寫入最大值爲100ns,然後睡眠100ns),但沒有運氣。

一個相關的問題:我如何直接檢查線程的優先級,並且/或者判斷它是否以實時方式開始,然後降級而不是提升爲開始?現在我只是從硬件性能上做出推論,所以很難確切地說出發生了什麼。

+0

的「USB串行」驅動程序沒有在「TXEMPTY」中斷,所以允許一個非輪詢界面?如果不是,它很糟糕。 –

+0

這是一個多線程的操作系統,它的調度程序應該是這樣做的。您能否更詳細地解釋爲什麼會出現這種問題(您運行的是關鍵生命的醫療設備?),並​​提供一些您正在經歷的速度範圍,以及一些有關環境的細節(其他在機器上運行的東西)?你有麻煩的變異原因,還是你試圖直接強迫一個實時/高優先級的線程?多線程操作系統上的應用程序通常需要很好地運行,並且必須將操作系統視爲調度的仲裁者。 – jefflunt

+1

@jefflunt是啊 - 聽起來像一些討厭的I/O輪詢 - 現代,先發制人的多任務者設計要避免的事情。 –

回答

0

我的建議是將執行線程需要最高優先級到單獨的進程。蘋果通常會爲實時處理(如駕駛內置攝像頭)執行此操作。根據您定位的操作系統的版本,您可以使用分佈式對象(XPC的前身)或XPC。

你也可以推出自己的RPC機制,並使用標準的Unix叉技術來創建一個單獨的子進程。由於您的主應用程序是子進程的所有者,因此除了進程內的單個線程優先級之外,您還應該能夠設置進程的調度優先級。

正如我編輯這篇文章,我有一個WWDC視頻播放的背景,也開始了QuickTime影片錄製任務。正如你所看到的,這些應用的實時性方面進行了單獨的XPC進程中運行:

ps -ax | grep Video 
1933 ??   0:00.08 /System/Library/Frameworks/VideoToolbox.framework/Versions/A/XPCServices/VTDecoderXPCService.xpc/Contents/MacOS/VTDecoderXPCService 
2332 ??   0:08.94 /System/Library/Frameworks/VideoToolbox.framework/Versions/A/XPCServices/VTDecoderXPCService.xpc/Contents/MacOS/VTDecoderXPCService 

XPC Services at developer.apple.com

Distributed Objects at developer.apple.com