溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Linux進程凍結(jié)的方法是什么

發(fā)布時間:2022-02-10 15:21:39 來源:億速云 閱讀:237 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“Linux進程凍結(jié)的方法是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Linux進程凍結(jié)的方法是什么”吧!

Linux休眠前需要先凍結(jié)所有進程,休眠喚醒后再解凍進程,驅(qū)動開發(fā)中的某些問題可能導致凍結(jié)進程失敗。

Linux進程凍結(jié)的方法是什么

1 什么是進程凍結(jié)

進程凍結(jié)技術(shù)(freezing of tasks)是指在系統(tǒng)hibernate或者suspend的時候,將用戶進程和部分內(nèi)核線程置于“可控”的暫停狀態(tài)。

2 為什么需要凍結(jié)技術(shù)

假設(shè)沒有凍結(jié)技術(shù),進程可以在任意可調(diào)度的點暫停,而且直到cpu_down才會暫停并遷移。這會給系統(tǒng)帶來很多問題:

(1)有可能破壞文件系統(tǒng)。在系統(tǒng)創(chuàng)建hibernate image到cpu down之間,如果有進程還在修改文件系統(tǒng)的內(nèi)容,這將會導致系統(tǒng)恢復之后無法完全恢復文件系統(tǒng);

(2)有可能導致創(chuàng)建hibernation image失敗。創(chuàng)建hibernation image需要足夠的內(nèi)存空間,但是在這期間如果還有進程在申請內(nèi)存,就可能導致創(chuàng)建失?。?/p>

(3)有可能干擾設(shè)備的suspend和resume。在cpu down之前,device suspend期間,如果進程還在訪問設(shè)備,尤其是訪問競爭資源,就有可能引起設(shè)備suspend異常;

(4)有可能導致進程感知系統(tǒng)休眠。系統(tǒng)休眠的理想狀態(tài)是所有任務(wù)對休眠過程無感知,睡醒之后全部自動恢復工作,但是有些進程,比如某個進程需要所有cpu online才能正常工作,如果進程不凍結(jié),那么在休眠過程中將會工作異常。

3 代碼實現(xiàn)框架

凍結(jié)的對象是內(nèi)核中可以被調(diào)度執(zhí)行的實體,包括用戶進程、內(nèi)核線程和work_queue。用戶進程默認是可以被凍結(jié)的,借用信號處理機制實現(xiàn);內(nèi)核線程和work_queue默認是不能被凍結(jié)的,少數(shù)內(nèi)核線程和work_queue在創(chuàng)建時指定了freezable標志,這些任務(wù)需要對freeze狀態(tài)進行判斷,當系統(tǒng)進入freezing時,主動暫停運行。

kernel threads可以通過調(diào)用kthread_freezable_should_stop來判斷freezing狀態(tài),并主動調(diào)用__refrigerator進入凍結(jié);work_queue通過判斷max_active屬性,如果max_active=0,則不能入隊新的work,所有work延后執(zhí)行。

標記系統(tǒng)freeze狀態(tài)的有三個重要的全局變量:pm_freezing、system_freezing_cnt和pm_nosig_freezing,如果全為0,表示系統(tǒng)未進入凍結(jié);system_freezing_cnt》0表示系統(tǒng)進入凍結(jié),pm_freezing=true表示凍結(jié)用戶進程,pm_nosig_freezing=true表示凍結(jié)內(nèi)核線程和workqueue。它們會在freeze_processes和freeze_kernel_threads中置位,在thaw_processes和thaw_kernel_threads中清零。

fake_signal_wake_up函數(shù)巧妙的利用了信號處理機制,只設(shè)置任務(wù)的TIF_SIGPENDING位,但不傳遞任何信號,然后喚醒任務(wù);這樣任務(wù)在返回用戶態(tài)時會進入信號處理流程,檢查系統(tǒng)的freeze狀態(tài),并做相應處理。

任務(wù)主動調(diào)用try_to_freeze的代碼如下:

static inline bool try_to_freeze_unsafe(void)

{if (likely(!freezing(current))) //檢查系統(tǒng)是否處于freezing狀態(tài)return false;return __refrigerator(false); //主動進入凍結(jié)

}

static inline bool freezing(struct task_struct *p)

{if (likely(!atomic_read(&system_freezing_cnt))) //系統(tǒng)總體進入freezingreturn false;return freezing_slow_path(p);

}

bool freezing_slow_path(struct task_struct *p)

{if (p-》flags & PF_NOFREEZE) //當前進程是否允許凍結(jié)return false;if (pm_nosig_freezing || cgroup_freezing(p)) //系統(tǒng)凍結(jié)kernel threadsreturn true;if (pm_freezing && ?。╬-》flags & PF_KTHREAD)) //系統(tǒng)凍結(jié)用戶進程return true;return false;

}
進入凍結(jié)狀態(tài)直到恢復的主要函數(shù):bool __refrigerator(bool check_kthr_stop)
{

。..for (;;) {
set_current_state(TASK_UNINTERRUPTIBLE); //設(shè)置進程為UNINTERRUPTIBLE狀態(tài)
spin_lock_irq(&freezer_lock);

current-》flags |= PF_FROZEN; //設(shè)置已凍結(jié)狀態(tài)if (!freezing(current) ||

(check_kthr_stop && kthread_should_stop())) //判斷系統(tǒng)是否還處于凍結(jié)

current-》flags &= ~PF_FROZEN; //如果系統(tǒng)已解凍,則取消凍結(jié)狀態(tài)

spin_unlock_irq(&freezer_lock);if (?。╟urrent-》flags & PF_FROZEN)) //如果已取消凍結(jié),跳出循環(huán),恢復執(zhí)行break;

was_frozen = true;

schedule();

}

。..。..

}

到此,相信大家對“Linux進程凍結(jié)的方法是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI