uC/OS-II windows下寄生模擬問題 後記

來源:互聯網
上載者:User

(本文原創,轉載請註明出處)


自《uC/OS-II Windows下虛擬問題》發表以後,很多朋友給我留言,:),在此,謝謝大家的批評指正。希望大家直接在我的Blog上留言,少用QQ留言,這些技術問題,在Blog上討論,會越辯越明。在QQ上留言,很容易一邊倒。

特別是“探路者”網友給我的留言,這裡貼出來,供大家一起研究:


2011-08-27 08:49:22  探路者:

uC/OS-II Windows下虛擬問題:我覺得你的分析存在問題的。
2011-08-27 08:51:47  探路者:
對於Windows和Linux來說,進程是作業系統能夠調度的最小單位,線程是進程能夠調度的最小單位。
2011-08-27 08:54:21  探路者:
ucosii程式,一個整體,是作為作業系統能夠調度的最小單位-進程來啟動並執行,作業系統不會認識到ucosii程式內部的運作,比如多線程。
2011-08-27 09:01:25  探路者:
對於作業系統來說,只有進程切換,而沒有線程切換。
2011-08-27 09:01:52  探路者:
對於單個進程來說,才會存線上程切換。
2011-08-27 10:06:04  探路者:
對於第一個問題:不存在單獨的線程切換,只存在進程的切換。雖然ucosii整體(進程)的即時性得不到最優的保證,但是ucosii整體(進程)的啟動並執行完整性是得到保證的。

2011-08-27 10:09:24  探路者:
對於第二個問題:既然訪問共用資源,那麼就一定會考慮互斥的問題了。訪問windows和linux作業系統的臨界資源的前後,考慮加鎖和解鎖,也是一件正常不過的事情。
2011-08-27 10:14:55  探路者:

請雪松大俠分析清楚,我對這個問題也是很著急,因為我就是這樣在用,而且想應用到一個控制系統中。如果我貿然使用,會出現《驚魂動車組》,就麻煩了。 

這裡我不想多說,《uC/OS-II Windows下虛擬問題》中已經說得非常清楚, 這裡舉上一個實際的例子:


void task1(void *param)

{

while (1)

{

        printf("Haha....you are in task 1.\n");

        OSTimeDly(40);

}

}


void task2(void *param)

{

    while(1)

    {

        printf("Haha, you are in task 2.\n");

        OSTimeDly(20);

    }

}

void task3(void *param)

{

    while(1)

    {

        printf("Haha, you are in task 3.\n");

        OSTimeDly(20);

    }

}

這三個任務是再簡單不過的任務了。現在假設任務1的優先順序別最高,任務2的優先順序別次之,任務3的優先順序別最低。printf這個函數都會往螢幕上輸出,windows 為了防止輸出錯亂,printf 函數內部是有一個 windows 的鎖,用來防止輸出到螢幕上的資料錯亂。正因為有了這個鎖,我們看到的輸出資訊不會有類似以下的輸出:

Haha, you are Haha, in task 2.

you are in task 3.

如果在windows上類比,使用了windows庫裡的printf函數,這個鎖是無法規避的。為了便於討論,我們把printf簡化為如下虛擬碼:

int printf(char *fmt, ...)

{

    char *lines[MAX_OUTPUT];

   

    *lines = '\0';

    ...;//output print data to lines;

    lockscreen();//acquire lock.

    output2screen(lines);

    unlockscreen();//release lock.

    return ...;

}


本來uC/OS-II運行到任務3的printf語句時如果全部完成,也沒什麼事情。假設如果運行到lockscreen()時,正在ouput2screen()呢。uC/OS-II覺得你的時間到了,運行任務1去了。如果運行到printf中的lockscreen()時,那麼task1就執行不下去了。只能執行其它任務,或者讓任務3執行下去,直到unlockscreen()。task1才能繼續執行。

我們來細細看一下:

lockscreen()並不是uC/OS-II的鎖。

uC/OS-II並不知道task3已經進入了一個臨界地區,在windows下的移植裡,uC/OS-II的核心會調用SuspendThread()掛起task3,task3並不會自己恢複執行,必須 uC/OS-II的調度演算法調用ResumeThread(),task3才能恢複執行。調度演算法調用ResumeThread恢複task1執行時,遇到lockscreen,task1進入阻塞狀態,這個阻塞狀態是windows的阻塞狀態,在uC/OS-II核心裡,task1仍然是運行態。
但實際上task1已經死了,所有低於task1優先順序的任務都Over了。如果 task1是最高優先順序任務,那麼整個uC/OS-II雖然沒有死,但現象就是全部都死了。


我想我講清楚整個過程了吧。模擬這個過程也很簡單,在 VC++上很容易線上這個問題。由於並不是必現的問題,多弄幾個printf任務,增大出現的幾率。通過thread觀察視窗和callstack視窗,可以明顯的看到task1和task3都停在了printf裡面。在windows的系統核心裡停下了。歡迎拍磚!!!

(本文原創,轉載請註明出處)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.