2017-09-24 165 views
0

我正在實現一個Win32控制檯文本編輯器,它有一個內部消息隊列,用於傳遞有關哪些區域需要重新繪製,消息來自插件等信息。我更喜歡它默認爲單線程(如果沒有任何事情發生這需要額外的線程)。我考慮2種消息隊列實施策略:文本編輯器是否可以將每個按鍵從一個線程傳遞到另一個線程?

  1. 使用通用隊列和Win32事件,所以我可以用WaitForMultipleObjectsEx同時等待內部消息和用戶輸入,同時傳遞控制檯輸入句柄和事件句柄。在這種情況下,文本編輯器可以完全在一個線程內生存。
  2. 使用I/O完成端口。在這種情況下,文本編輯器至少需要兩個線程,其中一個調用GetQueuedCompletionStatus來獲取消息,另一個讀取用戶輸入並通過PostQueuedCompletionStatus將其發送到隊列。控制檯輸入句柄的原因不能重疊,並且WaitFor*函數不能接受完成端口作爲等待句柄,所以不可能同時等待它們。就像在第一個設置中一樣,當沒有輸入或事件時,兩個線程都不會浪費CPU時間,但每個按鍵都必須通過IOCP從一個線程傳遞到另一個線程。

哪種設計總體上更好?

性能和延遲的缺點是將每個按鍵通過IOCP傳遞給文本編輯器很重要嗎?

+0

我不知道Windows,但你每秒鐘都會得到很少的按鍵。電腦速度很快。 –

+0

即使線程只是在內核模式下等​​待,如果您有無意義的線程,您仍然在浪費內存。 – Anders

+0

您是否考慮過使用[Qt](http://qt.io)等跨平臺工具包?然後你會做什麼工具包提供 –

回答

2

IOCP的性能和延遲對您而言是很好的。然而,我不會將每個按鍵轉換爲PostQueuedCompletionStatus。我寧願讓PostQueuedCompletionStatus一次排列多個按鍵,無論您從ReadConsoleInput得到多少數量。

我認爲性能差異很小,要麼環境可能更快。而WaitForMultipleObjects更容易實現。

P.S.你確定你需要消息隊列嗎?爲什麼不用任何線程處理這些重繪請求/插件消息,例如使用關鍵部分要防範(控制檯輸出+你的共享狀態)?如果擁擠程度很低,比如100Hz消息+ 15Hz按鍵,並且您可以快速處理它們,這將使您的延遲比IOCP或任何其他隊列的延遲更低:低擁塞或短暫鎖定時,關鍵部分甚至不會切換到內核鎖定/解鎖。這也將簡化設計,你的主線程將會阻塞ReadConsoleInput()調用,在此之前不需要WaitFor ..

+0

謝謝你的回答!我會考慮你建議的同步消息,至少對於某些類型的消息來說,它看起來好多了。有一個消息隊列+ WaitFor *'/'GetQueuedCompletionStatus'的原因是可以通過Alertable I/O或IOCP分別在主線程中執行I/O操作,也不需要完全重入,這是必需的(如果我的理解是正確的),如果一切都在原地調用。 – jhkouy78reu9wx

+0

@ jhkouy78reu9wx當您​​有多個線程處理完成請求或者您有超過MAXIMUM_WAIT_OBJECTS = 64個併發流時,IOCP僅比可警告的I/O更好。如果你沒有那麼多的流,我的期望是WaitForMultipleObjects和IOCP一樣快。 處理控制檯輸入與async IO在同一隊列中可能很有趣:用戶按下按鍵〜10Hz最大,異步IO可以以1 KHz或更高的速率完成,但延遲方式您希望優先處理用戶輸入。 WaitForMultipleObjects稍微好一些,因爲它按順序優先處理句柄。 – Soonts

相關問題