2013-02-13 53 views
2

今天我的老闆和我有一個關於一些代碼,我寫了討論。我的代碼從給定的HTTP/HTTPS鏈接下載3個文件。我有多線程下載,以便所有3個文件同時在3個獨立的線程中下載。在這次討論中,我的老闆告訴我,代碼將被運送給最有可能運行舊硬件和軟件的人員(我正在談論Windows 2000)。編程比較大的,線程應用程序的舊系統

直到這個時候,我從來沒有考慮線程化應用將如何擴展在老硬件。我意識到如果CPU只有1個內核,線程就沒用了,甚至可能會惡化性能。我一直在想這個下載任務是否是I/O操作。意思是說,如果一個API被阻塞等待來自HTTP/HTTPS服務器的信息,另一個想要做計算的線程會被同時調度嗎?較老的操作系統是否執行此類調度?

他說的另一件事:由於代碼將在舊機器上運行,我的應用程序不應該吃掉CPU。他說在CPU密集型任務之後調用Sleep()來讓其他程序有一些喘息的空間。現在我總是覺得在任何程序中使用Sleep()都很糟糕。我錯了嗎?什麼時候使用Sleep()是合理的?

感謝您的期待!

+3

我嚴重懷疑線程將是一個電線下載專用應用程序中的可擴展瓶頸,例如您所描述的。機會是管道飽和度將是你的限制因素。關於你的老闆「使用睡眠()」的口頭禪,......只是..哇。他認爲你的應用程序將在等待所有有線通信量時計算Pi數字? – WhozCraig 2013-02-13 16:52:55

+0

誰使用Windows 2000,他們需要升級。 :D – 2013-02-13 17:08:48

+1

@WhozCraig你想說它在等待I/O時不計算PI數字嗎?該死,我對世界的看法爆炸了;-) – junix 2013-02-13 17:37:06

回答

5

我一直在想這個下載任務是否是I/O操作。 意思是說,如果一個API被阻塞,等待來自 HTTP/HTTPS服務器的信息,那麼另一個想要執行一些 計算的線程會被同時調度嗎?較老的操作系統是否執行此類調度?

是的,他們這樣做。這是阻止IO的笑話。該線程被暫停並且其他計算(線程)發生,直到事件喚醒被阻塞的線程。這就是爲什麼即使是單核心機器將它分解成線程也是完全有意義的,而不是在單個線程中自己下載的時候安排一些窮人。

當然,您的下載相互影響有關帶寬,所以線程不會幫助用來加快下載:-)

另一件事,他說:由於代碼將被舊 的機器上運行,我的應用程序不應該吃CPU。他表示在CPU密集型任務之後調用Sleep() 以允許其他程序呼吸 空間。

實際上在完成任務後使用睡眠對此無濟於事。在計算一段時間之後進行睡眠(進行時間分割)然後再進行計算可能會有所幫助。但這僅適用於合作系統(例如Windows 3.11)。這對於先行系統不起作用,其中調度器使用時間分片將計算時間分配給線程。這將是想想,爲了給其他任務的優先級降低優先級CPU密集型任務更加重要......

現在我一直的印象是,使用睡眠()是在任何程序可怕 。我錯了嗎?什麼時候使用Sleep()對齊?

這真的取決於你在做什麼。如果您實施某種繁忙的等待某個特定標誌被設置的設置(可能在幾秒鐘之後),最好重新檢查一下,如果在休眠一段時間後它被設置爲了放棄預定的時間片,而不是僅僅用CPU檢查一個永遠不會被設置的標誌。

在現代系統中,在計算中引入睡眠是沒有意義的,因爲它只會減慢計算速度。

調度取決於操作系統的調度程序。他是一個擁有「大畫面」的人。在我看來,每一種「做得更好」的方法只有在特定應用程序的範圍內纔有效,您可以在這裏看到對調度程序不明顯的某些關係的概述。

附錄: 我做了一些研究,發現Windows支持從Windows 95搶先多任務。 Windows NT行(Windows 2000所屬的行)始終支持搶先式多任務處理。

+1

Sleep()不應該被誤用於線程間通信。 Windows API具有事件和信號燈信號。用Sleep()循環輪詢一個標誌是一個典型的失敗。 – 2013-02-13 17:44:47

+0

@MartinJames絕對同意。這只是一個嘗試找到一個例子,爲什麼使用睡眠本身並不被認爲是有害的。也許有更好的... – junix 2013-02-13 17:48:30

+0

謝謝你的回答!的確有用的見解!你知道/聽說過任何有經驗的程序員曾經在他們的任何程序中使用過Sleep()嗎?只是好奇哈哈 – 2013-02-13 18:13:29