若一個函數是可重入的,則該函數:
(1) 不能含有靜態(全局)非常量數據
(2) 不能返回靜態(全局)非常量數據的地址
(3) 只能處理由調用者提供的數據
(4) 不能依賴於單實例模式資源的鎖
(5) 不能調用(call)不可重入的函數(調用的函數必須滿足前面的要求)
(6) 多“用戶、對象、進程優先級”以及多進程,一般會使得可重入代碼變得複雜。同時I/O代碼通常時不可重入的,因爲他們依賴於像磁盤這樣共享的、單獨的資源
(7) 在和硬件發生交互的時候,切記執行類似Disinterrupt()之類的操作,就是關閉硬件中斷。完成交互記得打開中斷,在有些系列上,這叫做“進入/退出核心”或者用OS_ENTER_KERNAL/OS_EXIT_KERNAL來描述。//這是臨界區保護
(8) 謹慎使用堆棧。最好先在使用前先OS_ENTER_KERNAL。
等等吧,總之,時刻記住一句話:保證中斷是安全的!
與線程安全的關係
可重入與線程安全都關係到函數處理資源的方式。但他們有一定的區別,可重入觀念會影響到函數的外部接口,而線程安全只關心函數的具體實現
可重入是在單線程操作系統背景下,重入的函數或者子程序,按照後進先出的線性序依次執行完畢。多線程執行的函數或子程序,各個線程的執行時機是由操作系統調度,不可預期的,但是該函數的每個執行線程都會不時的獲得CPU的時間片,不斷向前推進執行進度。
VxWorks中採取的可重入的技術有:
* 動態堆棧變量(各子函數有自己獨立的堆棧空間)
* 受保護的全局變量和靜態變量
* 任務變量