2014-10-02 42 views
3

我有一個關於替代方法延遲除了睡覺的C++程序的問題。替代方法來延遲我的程序而不睡覺,因爲在C++中使用異步IO?

我有我的程序的一部分接收和發送UDP數據包到控制器。這部分程序必須異步運行。爲了減少此提供程序的開銷,我決定使用異步IO來接收UDP數據包,而不是使用單獨的線程來監視套接字。

我也跟着的sigaction的this例子來做到這一點。我注意到,如果我在嘗試使用這個sigaction的時候嘗試使用usleep,那麼每當我收到一個數據包的時候就會打破我的睡眠。這種說法是有道理的,因爲我認爲sigaction是由CPU上的某種中斷觸發的,這可能會阻止CPU進入休眠狀態。如果任何人有一個很好的解釋爲什麼會發生這種情況,我會很好奇知道。我的問題是,有時我必須連續發送幾個數據包,並且需要確保延遲它們,否則我的控制器會錯過它們。

我通常會使用睡眠延遲發送數據包,但現在我不能,因爲它得到通過我的sigaction打破。我曾想過可能會忙於等待,但這可能太不一致了。我也有關於可能使用一個定時清空的數據包隊列,但似乎可能有一個更簡單的解決方案。

除了睡眠之外,還有其他延遲發送數據包的方式嗎?有沒有辦法設置我的異步IO,所以它不會打破睡眠?我是否以錯誤的方式解決了這個問題?

+6

如果您發現需要休眠直到異步操作完成,那麼您根本沒有任何用於異步的用途。不妨同步做。 – 2014-10-02 18:40:00

+0

我應該澄清只有接收是異步完成的。只要我在主進程中發送一個數據包,發送就完成了。問題是異步操作會中斷所有初始化線程中的睡眠。 – 2014-10-02 19:38:11

回答

4

通常,在編寫異步程序時,切換到事件循環編程風格。任何事件系統都會給你設置觸發回調的定時器的能力,使用那些你可以設置時間表來發送流量和類似的事情。此外,您通常會使用它們來觀察套接字,並在需要閱讀內容時調用回調函數。雖然對於UDP並不重要,但如果您在任何時候都處理TCP,那麼當套接字準備好寫入時,您也希望使用它們來調用回調函數,這樣,在嘗試寫出數據時永遠不會阻塞進程。

我個人很喜歡http://libevent.org/雖然我聽說過libev的好東西爲好。

+0

感謝您的意見。我認爲你是對的,我應該轉向更多的事件驅動結構。無論如何,我真的不應該用睡覺來控制流量。感謝您的鏈接,我會檢查出libevent。 – 2014-10-02 19:43:39

2

這應該澄清一些事情:

從睡眠手冊:

Return Value 
Zero if the requested time has elapsed, or the number of seconds left to sleep, if the call was interrupted by a signal handler. 

一種選擇是創建循環,其檢查(如中斷,因爲左秒休眠恢復數量)如果時間已經過去或不。如果不是隻是執行另一次睡眠等,則需要時間結束。

+0

這是一個不錯的主意,我忘了它返回了一個值。編輯:其實我使用usleep,因爲我需要毫秒的精度,它只返回-1或0,(http://linux.die.net/man/3/usleep),但感謝您的建議! – 2014-10-02 20:02:52

+0

那麼你可以嘗試nanosleep(手冊): 如果調用被信號處理程序中斷,nanosleep()返回-1,將errno設置爲EINTR,並將時間寫入到由rem除非rem爲NULL。 * rem的值然後可用於再次調用 nanosleep()並完成指定的暫停(但請參閱NOTES)。 – RaFD 2014-10-02 20:09:04

+0

好想法謝謝! – 2014-10-02 20:31:13