程式設計之美複習筆記

Avril發表於2013-08-30

 

 

1.10 雙執行緒高效下載

偽碼給出了典型的生產者消費者問題解答,用一個訊號量(semaphore)表示剩餘空閒塊數(g_seEmpty),一個訊號量表示已下載記錄數(g_seFull)。

下載執行緒中消耗空閒塊,所以先g_seEmpty.Unsignal(),相當於P(g_seEmpty),完成後g_seFull.Signal(),相當於V(g_seFull)。寫磁碟執行緒則恰好相反,先g_seFull.Unsignal(),相當於P(g_seFull),完成後g_seEmpty.Signal(),相當於V(g_seEmpty)。

值得注意的是Thread的建構函式中指定的是函式指標:Thread(void (*work_func)());這樣就可以為不同的執行緒指定不同的工作函式了。

回顧一下PV操作:

procedure p(var s:samephore);
{
  s.value=s.value-1;
  if (s.value<0) asleep(s.queue);
}
procedure v(var s:samephore);
{
  s.value=s.value+1;
  if (s.value<=0) wakeup(s.queue);
}
與semaphore的機制是一樣的,當使用semaphore進行計數時,count==0時將當前的thread阻塞。
後續問題:
1.多個下載執行緒的實現
TODO
如果直接加入多個下載執行緒,由於下載完成順序是不一定的,如何保證訪問儲存的順序是有序的?為每一個block加鎖?
 
2.windows中有哪些API可以瞭解使用者是否在使用滑鼠或者鍵盤
(1)GetInputState
函式原型: BOOL GetInputState(VOID);
函式功能:該函式確定在當前執行緒的訊息佇列中是否有要處理的滑鼠,鍵盤訊息.
注意事項:返回值指定是否發生了滑鼠,鍵盤輸入.如果檢測到輸入的話,則返回值為非零值,否則返回值為零

(2)GetLastInputInfo
函式原型:BOOL WINAPI GetLastInputInfo( __out PLASTINPUTINFO plii);
函式功能:獲取上次輸入操作的時間
引數:[out] 型別:PLASTINPUTINFO結構
一個指向接收到最後一個輸入事件時間的LASTINPUTINFO結構指標。
返回值:如果呼叫函式成功,返回值為非零。
 如果呼叫函式失敗,返回值為零。
說明:呼叫函式GetLastInputInfo()以後, 結構成員lpi.dwTime 中的值並非上次輸入事件發生以後的毫秒數。而是上次輸入事件發生時的系統執行時間。相當於上次輸入事件發生時執行了lpi.dwTime=::GetTickCount()。::GetTickCount()-lpi.dwTime才是上次輸入事件發生以後的毫秒數。
 
比較著名的問題有:生產者消費者問題,讀者寫者問題,迴圈佇列讀寫問題,等。
 
 
 
 
 

相關文章