(1)時序競態:前后兩次運行同一個程序,出現的結果不同。
(2)pause函數:使用該函數會造成進程主動掛起,并等待信號喚醒,調用該系統調用的進程會處于阻塞狀態(主動放棄CPU)
? ? ? ? ? 函數原型:int pause(void);? 返回值為-1,并設置errno為EINTR
? ? ? ? ?
? ? ?使用pause和alarm實現sleep函數;
(3)時序問題分析
? ? ? ? ? ? ? 1)如果在執行完函數alarm函數調用時(還沒有計時完),此時進程失去cpu,進入就緒等待狀態。
? ? ? ? ? ? ? 2)定時時間到,內核向當前進程發送SIGALRM信號,信號無法被處理,信號處于阻塞等待狀態。
? ? ? ? ? ? ? 3)當進程再次獲得cpu資源時,SIGALRM信號被遞達,信號捕捉,執行捕捉函數。
? ? ? ? ? ? ? 4)捕捉函數結束后,返回當前進程主控流程,pause()被調用掛起等待,無法被喚醒。
? ? 主要原因:是因為在alarm函數和pause函數之間執行的時間比定時長,導致定時完了還沒執行pause函數。
?(4)解決方法:使用sigsuspend函數(在嚴格要求時序的場合下使用)
? ? ? ? ?函數原型:int sigsuspend(const sigset_t *mask)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?sigsuspend調用期間,進程信號屏蔽字由參數mask指定。
? ? ?實現原理:在sigsupend調用之前屏蔽該信號,臨時信號屏蔽字mask中解屏蔽這個信號,那么信號來的時候在sigsuspend中是將信號阻塞,在mask中則使用該信號。
(5)總結
? ? ? ? ? ?競態條件和系統負載有很緊密的關系,體現出信號的不可靠性。針對于這種情況,應提早預見,主動規避。? ? ? ? ? ? ?
?
?
?