2010-03-12 39 views
3

我有一個用C語言編寫的守護程序應用程序,當前在Solaris 10計算機上沒有已知問題。我正在將它移植到Linux上。我不得不做出最小的改變。在測試期間,它通過所有的測試用例它的功能沒有問題。但是,當我在Solaris計算機上「閒置」時查看其CPU使用率時,它使用的CPU是大約.03%。在運行紅帽企業版Linux 4.8的虛擬機上,同一進程使用所有可用的CPU(通常位於90%+範圍內)。在無限循環內的select()在RHEL 4.8虛擬機上使用的CPU數量遠遠多於在Solaris 10計算機上的CPU數量

我首先想到的是事件循環必須有錯誤。事件循環是一個無限循環(while(1)),致電select()。 timeval設置爲timeval.tv_sec = 0timeval.tv_usec = 1000。這似乎對於該流程正在做的事情來說足夠合理。作爲一個測試,我碰到了timeval.tv_sec。即使這樣做後,我看到了同樣的問題。

有什麼我不知道如何選擇在Linux和Unix上的作品?或者它與在虛擬機上運行的操作系統有什麼不同?或者也許還有一些我完全錯過的東西?

還有一件事我不確定正在使用哪個版本的vmware服務器。不過,它在一個月前剛剛更新。

回答

5

我相信Linux通過將其寫入select()調用的time參數來返回剩餘時間,而Solaris不會。這意味着不瞭解POSIX規範的程序員可能不會重置要選擇的調用之間的時間參數。

這將導致第一次呼叫有1000次使用超時,所有其他呼叫使用0次使用超時。

+0

太棒了!這是問題。謝謝! – Jake 2010-03-12 20:27:57

1

正如Zan Lynx所說,timeval是通過在linux上進行選擇來修改的,因此您應該在每次select調用之前重新分配正確的值。另外,我建議檢查一些文件描述符是否處於特定狀態(例如文件結束,對等連接關閉......)。也許移植在返回值(FD_ISSET等)的分析中顯示出一些潛在的錯誤。它在幾年前發生在一個選擇驅動循環的端口:我以錯誤的方式使用返回的值,並且關閉的fd被添加到rd_set,導致select失敗。在舊的平臺上,錯誤的fd被使用的值高於maxfd,因此被忽略。由於相同的錯誤,程序無法識別選擇失敗(select()== -1)並永遠循環。

再見!

+0

這是一個很好的觀點......我現在正在研究這個問題。謝謝! – Jon 2010-03-12 21:22:00

相關問題