可重入程序與不可重入程序的區分


       可重入性的英文關鍵詞為Reentrancy,這里首先要區分可搶占這一概念。在計算機里面,程序的運行可以說是一堆機器指令被放入CPU進行順序執行, 但是操作系統為了更好地管理程序,就出現了各式各樣的載體概念,比如說進程、線程、任務,究其本質,都是相對於“調度”這個操作,它們只是調度的粒度不一 樣。如果我們在Linux或者windows下運行某個程序,它會依托於進程或者任務載體,由操作系統的內核對它進行調度執行。可搶占式說明當前你執行的 程序(任務)可以被其它程序搶占,意味着暫時失去對CPU資源的擁有。

        一旦涉及到調度,就需要對任務之間進行同步和互斥了,比如常見的觸發調度的技術如中斷、任務睡眠、內核搶占等。

        我在這里舉的例子是可重入型函數,這也是可重入性的基礎,其它引申出來的概念或者應用都是建立在它上面的。可重入型函數任何時候都可以被中斷,一段時間以后又可以運行,而相應數據不會丟失。可重入型函數只使用局部變量,即變量保存在CPU寄存器中或棧中。

1     void strcpy(char *dest, char *src)  
2     {  
3         while (*dest++ = *src++) {  
4             (void)0;  
5         }  
6         *dest = NUL;  
7     }  

  strcpy()是屬於可重入型函數,多個任務或者線程調用它之后,並不會帶來同步等問題。

        如果說某個函數使用的變量涉及到全局變量或者堆,這樣的函數就可能是不可重入型函數了,有可能得解決資源互斥的問題。在嵌入式研發中,可以利用開關中斷、 任務優先級調整,信號量,自旋鎖等多種手段來解決不可重入的問題。舉個常見的例子,使用全局變量的函數也並非一定是不可重入的,例如該全局變量已經被賦值 且只讀性質。

        再舉一個實際例子,某個函數的內部並不是所有代碼都是不可重入的,如果有相當部分代碼並不涉及資源互斥,這時候就可以采用加鎖解鎖的方式來進行任務之間同 步,達到邏輯意義上的可重入。當然,程序的邏輯還得設計人員自己控制,否則容易出現多個任務調用同一段代碼,誰也無法獲得執行權,造成死鎖的情況。

 

總結:可重入性是多任務、多線程開發的一個重要概念,特別在設計之初要予以考慮。另外對於很多系統調用或者說第三方函數庫,對於模塊是否可重入應該小心求證。   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM