和dede聊OS
dede提出了一個用互斥量(Mutex)模擬信號量(Semaphore)的課題,非常有趣。
dede提出的方案應該這樣,用i作為狀態標識:
?? ?lock(i_m);
??? if (i > 0) {
??????? i--;
??????? unlock(i_m);
??????? enter_critical_region();
??????? lock(i_m);
??????? i++;
??????? unlock(i_m);
??? } else {
??????? unlock(i_m);
??????? lock(m);
??????? enter_critical_region();
??????? unlock(m);
??? }
如果沒有理解錯,信號量用于限制可同時進入關鍵區域的線程個數,而i也起到這個目的。那么當線程陸續創建并陸續退出的時候(在一定時間后,線程數目保持 在多于關鍵區域可接受線程個數),那么會不會造成計數的問題呢?在上半條件分支里的關鍵區域執行完畢后并不會開啟鎖。而當有線程被掛起在下半分支的時候,如果上半分支的線程推到一定程度,則上半分支打開,以后進來的線程都在上半分支運行,于是下半分支的線程就餓死了。
根據dede的思路,我一開始這樣寫:
??? lock(i_m);
??? if (i > 0)
??? {
??????? i--;
??????? unlock(i_m);
??????? enter_critical_region();
??? }
??? else
??? {
??????? i--;
??????? unlock(i_m);
??????? lock(m);
??????? enter_critical_region();
??????? unlock(m);
??? }
??? lock(i_m);
??? i++;
??? unlock(i_m);
然后,仔細查看了一下發現也不對。因為這仍舊沒有解決下半分支線程餓死的可能。于是考慮在上半部分線程執行完畢后也應當開鎖(開著的鎖再開一次則忽略),因為線程數的最大情況是在達到線程容限時,只要有線程退出,就允許有線程進入。于是寫了下面的代碼:
??? lock(i_m);
??? if (--i < 0)
??? {
??????? lock(m);
??? }
??? unlock(i_m);
??? enter_critical_region();
??? lock(i_m);
??? i++;
??? unlock(i_m);
??? unlock(m);
這個代碼的正確性也需要驗證。然而這樣的替代應該還是不能算完全的,因為信號量主要在生產者/消費者模型中使用,替代代碼顯然無法對對方的行為做出反應。如果要做出反應可能就需要循環,這樣就陷入dede前一封信中提到的spin lock問題。
以上想法并不成熟,隨時補完。
dede提出的方案應該這樣,用i作為狀態標識:
?? ?lock(i_m);
??? if (i > 0) {
??????? i--;
??????? unlock(i_m);
??????? enter_critical_region();
??????? lock(i_m);
??????? i++;
??????? unlock(i_m);
??? } else {
??????? unlock(i_m);
??????? lock(m);
??????? enter_critical_region();
??????? unlock(m);
??? }
如果沒有理解錯,信號量用于限制可同時進入關鍵區域的線程個數,而i也起到這個目的。那么當線程陸續創建并陸續退出的時候(在一定時間后,線程數目保持 在多于關鍵區域可接受線程個數),那么會不會造成計數的問題呢?在上半條件分支里的關鍵區域執行完畢后并不會開啟鎖。而當有線程被掛起在下半分支的時候,如果上半分支的線程推到一定程度,則上半分支打開,以后進來的線程都在上半分支運行,于是下半分支的線程就餓死了。
根據dede的思路,我一開始這樣寫:
??? lock(i_m);
??? if (i > 0)
??? {
??????? i--;
??????? unlock(i_m);
??????? enter_critical_region();
??? }
??? else
??? {
??????? i--;
??????? unlock(i_m);
??????? lock(m);
??????? enter_critical_region();
??????? unlock(m);
??? }
??? lock(i_m);
??? i++;
??? unlock(i_m);
然后,仔細查看了一下發現也不對。因為這仍舊沒有解決下半分支線程餓死的可能。于是考慮在上半部分線程執行完畢后也應當開鎖(開著的鎖再開一次則忽略),因為線程數的最大情況是在達到線程容限時,只要有線程退出,就允許有線程進入。于是寫了下面的代碼:
??? lock(i_m);
??? if (--i < 0)
??? {
??????? lock(m);
??? }
??? unlock(i_m);
??? enter_critical_region();
??? lock(i_m);
??? i++;
??? unlock(i_m);
??? unlock(m);
這個代碼的正確性也需要驗證。然而這樣的替代應該還是不能算完全的,因為信號量主要在生產者/消費者模型中使用,替代代碼顯然無法對對方的行為做出反應。如果要做出反應可能就需要循環,這樣就陷入dede前一封信中提到的spin lock問題。
以上想法并不成熟,隨時補完。
轉載于:https://www.cnblogs.com/quanben/archive/2007/04/13/3129010.html
總結
- 上一篇: 关于批量发布blog的问题
- 下一篇: 软件项目管理(5)