[英]How to only barely use the bandwidth available to your program
我正在制作一個程序,將下載一堆不同的項目。 我的語言具有廉價的並發性,所以我首先想到我可以一次下載它們。 問題是使用你沒有的並發性是不好的 。 如果我嘗試一次性下載它們,用戶必須等到所有這些才能獲得它們之前。
假設您正在下載10個可以以7 mb / s的速度下載的項目,並且您的下載速度為20 mb / s。 該程序應該只開始下載前三項 ,並且只有在舊項目完成且有帶寬后才開始下載新項目。 另請注意,一般情況下,項目的下載速度不同。
如果我有一些程序化的方法來檢查網絡飽和度,這將很容易(只需檢查它是否在產生新線程之前已經飽和。)
正如評論中指出的那樣,你做得不夠好,無法做出任何保證。 但是,無論如何,假設你想要做到最好。
這個問題有兩個部分:
通過限制從套接字讀取的速率,可以在用戶空間程序中大致控制所消耗的帶寬。 TCP / IP堆棧將通知連接的另一端,該隊列正在代表您的應用程序進行維護,並且不會再發送任何其他內容。 實現速率限制的便捷方式是使用令牌桶 。
快速令牌桶實施:
int bucket = 0;
start_thread({ while(transfer_in_progress) {
bucket += bytes_per_second_limit;
sleep(1);
});
while(transfer_in_progress) {
bytesread = read(socket, buffer, min(bucket, buffersize), );
bucket -= bytesread;
}
如果bytes_per_second_limit
大致設置為可用帶寬(以字節/秒表示),則應該以連接允許的速度讀取。 如果連接速度更快,您將被限制為bytes_per_second_limit
。 如果連接速度較慢 ,則bucket
將以與速度限制和可用帶寬之間的差異成比例的速度永久增長。
哼!
如果您運行另一個線程,並密切關注bucket
,您可以觀察兩個條件:
bucket
始終為0,則可用帶寬更多,並且可以增加bytes_per_second_limit
,可能受限於您最近對可用帶寬的最佳猜測(來自#2)。 或者開始額外下載。 bucket
大於您上次查看的時間,並且數據點的最后幾秒似乎表示持續增長(可能進行線性回歸;無論您喜歡什么),以字節/秒表示的增長率是多少可以減少bytes_per_second_limit
,以使您的下載速率與可用帶寬相匹配。 所有這一切的問題在於無法保證您的帶寬保持不變。 線程監控bucket
可能會在增加速率和限制速率之間來回反彈。 我建議您在進行速率限制更改之前,先平均至少10或20秒。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.