學習Linux進程凍結技術

原文:蝸窩科技Linux進程凍結技術

功耗中經常需要用到,但是linux這塊了解甚少,看到這個文章還蠻適合我閱讀的

1 什么是進程凍結

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

2 為什么需要凍結技術

假設沒有凍結技術,進程可以在任意可調度的點暫停,而且直到cpu_down才會暫停并遷移。這會給系統帶來很多問題:

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

(2)有可能導致創建hibernation image失敗。創建hibernation image需要足夠的內存空間,但是在這期間如果還有進程在申請內存,就可能導致創建失敗;

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

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

3 代碼實現框架

凍結的對象是內核中可以被調度執行的實體,包括用戶進程、內核線程和work_queue。用戶進程默認是可以被凍結的,借用信號處理機制實現;內核線程和work_queue默認是不能被凍結的,少數內核線程和work_queue在創建時指定了freezable標志,這些任務需要對freeze狀態進行判斷,當系統進入freezing時,主動暫停運行。

0

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

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

任務主動調用try_to_freeze的代碼如下:

/**?* @brief 嘗試將當前任務(進程)主動置入凍結狀態(非安全上下文)?* @return bool - true: 凍結成功;false: 未觸發凍結條件?* @note 此函數通常在原子上下文或中斷禁用場景調用,需確保無鎖競爭風險?*/static inline bool try_to_freeze_unsafe(void){? ? // 檢查當前進程是否滿足凍結條件(通過freezing(current)快速判斷)? ? if (likely(!freezing(current)))?? ? ? ? return false; // 系統未啟用凍結或當前進程無需凍結? ? // 調用核心凍結邏輯,參數false表示非強制凍結(允許進程自行處理信號等)? ? return __refrigerator(false);?}/**?* @brief 快速檢查系統全局凍結狀態及當前進程的凍結條件?* @param p - 待檢查的進程描述符(struct task_struct指針)?* @return bool - true: 需要凍結;false: 無需凍結?* @note 通過原子變量system_freezing_cnt優化高頻調用的性能?*/static inline bool freezing(struct task_struct *p){? ? // 原子讀取系統全局凍結計數器,若為0則快速返回(likely優化分支預測)? ? if (likely(!atomic_read(&system_freezing_cnt)))? ? ? ? return false; // 系統未啟用凍結功能? ? // 進入慢速路徑,進一步檢查進程特定的凍結條件? ? return freezing_slow_path(p);}/**?* @brief 慢速路徑檢查進程的詳細凍結條件?* @param p - 待檢查的進程描述符?* @return bool - true: 需凍結;false: 豁免凍結?* @note 此函數處理以下凍結策略:?* ? ? ? 1. PF_NOFREEZE標記的進程(如內核關鍵線程)始終豁免?* ? ? ? 2. 系統級凍結(pm_nosig_freezing)或cgroup凍結策略?* ? ? ? 3. 用戶進程凍結(pm_freezing)且非內核線程?*/bool freezing_slow_path(struct task_struct *p){? ? // 檢查進程是否標記為禁止凍結(如某些關鍵內核線程)? ? if (p->flags & PF_NOFREEZE) ?? ? ? ? return false; // 明確豁免凍結? ? // 檢查系統是否處于"無信號"凍結模式(如休眠時凍結內核線程)? ? // 或進程屬于需凍結的cgroup? ? if (pm_nosig_freezing || cgroup_freezing(p)) ?? ? ? ? return true; // 強制凍結? ? // 檢查系統是否在凍結用戶進程,且當前進程為用戶進程(非內核線程)? ? if (pm_freezing && !(p->flags & PF_KTHREAD))?? ? ? ? return true; // 凍結用戶空間進程? ? return false; // 默認不凍結}

進入凍結狀態直到恢復的主要函數:

bool __refrigerator(bool check_kthr_stop)???????

for (;;) { ?// 無限循環,直到滿足解凍條件? ? /* 1. 設置進程為不可中斷睡眠狀態(D狀態)? ? ?* - TASK_UNINTERRUPTIBLE 確保進程不會被信號喚醒,僅能通過內核主動喚醒? ? ?* - 這種狀態是凍結進程的核心,避免進程在凍結期間被調度執行 */? ? set_current_state(TASK_UNINTERRUPTIBLE);? ? /* 2. 獲取 freezer_lock 自旋鎖并禁用中斷(spin_lock_irq)? ? ?* - 保護對 current->flags 的原子修改,防止競態條件? ? ?* - 禁用中斷避免中斷處理程序并發訪問凍結狀態 */? ? spin_lock_irq(&freezer_lock);? ? /* 3. 標記當前進程為已凍結(PF_FROZEN)? ? ?* - PF_FROZEN 是凍結完成的標志,被 thaw_processes() 等解凍函數檢測? ? ?* - 此處僅設置標志,實際凍結通過后續 schedule() 放棄CPU實現 */? ? current->flags |= PF_FROZEN;? ? /* 4. 檢查是否需要解除凍結:? ? ?* - freezing(current): 系統是否仍要求凍結(如休眠未完成)? ? ?* - kthread_should_stop(): 內核線程是否收到停止信號(如模塊卸載)? ? ?* 若任一條件為真,則清除 PF_FROZEN 標志,準備退出循環 */? ? if (!freezing(current) || (check_kthr_stop && kthread_should_stop()))? ? ? ? current->flags &= ~PF_FROZEN; ?// 清除凍結標志? ? spin_unlock_irq(&freezer_lock); ?// 釋放鎖并恢復中斷? ? /* 5. 檢查是否已解除凍結:? ? ?* - 若 PF_FROZEN 被清除,則跳出循環,恢復執行? ? ?* - 否則繼續進入調度等待 */? ? if (!(current->flags & PF_FROZEN))? ? ? ? break;? ? /* 6. 記錄凍結狀態并主動放棄CPU? ? ?* - was_frozen 用于返回是否曾被凍結(用于統計或調試)? ? ?* - schedule() 觸發進程切換,當前進程進入睡眠隊列,直到被解凍喚醒 */? ? was_frozen = true;? ? schedule(); ?// 調用調度器,進程進入睡眠狀態}

4 參考文獻

(1)http://www.wowotech.net/linux_kenrel/suspend_and_resume.html

(2) http://www.wowotech.net/linux_kenrel/std_str_func.html

(3) kenrel document: freezing-of-tasks.txt

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/88157.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/88157.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/88157.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GitHub 趨勢日報 (2025年06月22日)

📊 由 TrendForge 系統生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日報中的項目描述已自動翻譯為中文 📈 今日獲星趨勢圖 今日獲星趨勢圖 624 LLMs-from-scratch 523 ai-engineering-hub 501 n8n 320 data-engineer-handb…

kotlin中為什么新增擴展函數功能?

在 Kotlin 中,擴展函數的本質是「不修改原有類代碼,為其新增功能」,這源自編程中「開閉原則」(對擴展開放,對修改關閉)的第一性原理。 核心需求:當需要給第三方庫的類(如 Android 的…

excel 數據透視表介紹

Excel 數據透視表(PivotTable)就是你的數據分析神器!它能幫你快速匯總、分類、比較和分析 大量數據,從看似雜亂無章的表格中一鍵提取關鍵信息 ,生成交互式的匯總報告。無需復雜公式,只需拖拽幾下,就能讓數據“開口說話”&#xff…

半導體行業中的專用標準產品ASSP是什么?

半導體行業中的專用標準產品ASSP是什么? “專用標準產品”(ASSP - Application Specific Standard Product)是半導體集成電路中的一個重要分類。 你可以把它理解為介于通用標準產品和全定制ASIC之間的一種芯片。以下是它的核心定義和特點&a…

秋招Day14 - MySQL - 鎖

MySQL中有幾種類型的鎖? 鎖粒度來分,有表鎖、頁鎖和行鎖。 加鎖機制劃分,有樂觀鎖和悲觀鎖。 按兼容性劃分,有共享鎖和排他鎖。 按鎖模式劃分,有記錄鎖,間隙鎖,next-key鎖,意向鎖…

/var/lib/docker/overlay2目錄過大怎么辦

/var/lib/docker/overlay2 是 Docker 默認用于存儲 容器鏡像和容器運行時數據 的核心目錄,基于 overlay2 存儲驅動實現。以下是其具體作用和內容的詳細解析: 1. overlay2 目錄的作用 存儲鏡像分層結構: Docker 鏡像采用分層設計,o…

JimuReport:一款免費的數據可視化報表工具

JimuReport(積木報表)是一款免費的企業級數據可視化報表軟件,提供拖拽的方式像搭建積木一樣完成在線設計,功能涵蓋數據報表、打印設計、圖表報表、門戶設計、大屏設計等。 數據源 JimuReport 支持 30 多種數據源,包括…

Neo4j.5.X社區版創建數據庫和切換數據庫

在使用Neo4j數據庫(版本:neo4j-community-5.22.0)時,系統自帶的“neo4j”和“system”數據庫適用于日常的簡單學習和練習,但對于新的項目,將項目數據與練習數據混用會帶來諸多不便,例如查詢效率…

DAY33神經網絡

浙大疏錦行 定義了一個簡單的神經網絡,主要是掌握pytorch框架

拼團系統多層限流架構詳解

拼團系統多層限流架構詳解 一、整體架構設計理念 多層限流采用"層層設防"思想,通過網關層全局流量控制→服務層接口粒度限流→本地資源隔離→熱點參數精準防護的四級防御體系,實現從粗到細的流量治理,確保大促期間系統穩定性。 …

[ctfshow web入門] web92 `==`特性與intval特性

信息收集 和之前的題差不多,這次是使用了不嚴格相等的,詳情看這篇博客: 和 在 PHP 中有何區別?一共包含哪些部分? 首先,不能使$num 4476,然后需要使intval($num,0)4476 include("flag…

在Springboot項目部署時遇到,centos服務器上,curl請求目標地址不通 ,curl -x 可以請求通的解決辦法

在甲方服務器部署項目時,通常遇到需要開通外網權限的問題,有的是直接給開通服務器的白名單,就可以直接訪問白名單外網地址了。也有的是通過網絡轉發,將url前面的部分替換,可以進行網絡請求。有一次遇到一個罕見的&…

Python異步爬蟲編程技巧:從入門到高級實戰指南

Python異步爬蟲編程技巧:從入門到高級實戰指南 🚀 📚 目錄 前言:為什么要學異步爬蟲異步編程基礎概念異步爬蟲核心技術棧入門實戰:第一個異步爬蟲進階技巧:并發控制與資源管理高級實戰:分布式…

JMeter-SSE響應數據自動化3.0

背景 此次因為多了一些需要過濾排除的錯誤(數量很少),還需要修改下JMeter的jtl文件輸出數據(后續統計數據需要) 所以只涉及到JSR腳本的一些改動(此部分改動并不會影響到JMeter的HTML報告) 改動 主要通過設置JMeter中prev輸出數據變量threadN…

012 進程狀態和優先級

🦄 個人主頁: 小米里的大麥-CSDN博客 🎏 所屬專欄: Linux_小米里的大麥的博客-CSDN博客 🎁 GitHub主頁: 小米里的大麥的 GitHub ?? 操作環境: Visual Studio 2022 文章目錄 進程狀態和優先級一、進程狀態分類特殊狀態說明 二、如何查看進程…

React JSX原理

JSX本質 實質上是React.createElement()的語法糖

Java-51 深入淺出 Tomcat 手寫 Tomcat 類加載機制 雙親委派機制 生命周期 插件化

點一下關注吧!!!非常感謝!!持續更新!!! 🚀 AI篇持續更新中!(長期更新) 目前2025年06月13日更新到: AI煉丹日志-28 - Aud…

從C++編程入手設計模式——責任鏈模式

從C編程入手設計模式——責任鏈模式 ? 當我們的一個請求需要多個對象去處理,但具體由誰來處理,是根據情況動態決定的。例如,一個日志系統中,可能希望把錯誤信息寫入文件,把提示信息輸出到控制臺,而不是每…

泛型方法調用需要顯示指定泛型類型的場景

泛型類型的推斷確定 一般來說&#xff0c;泛型類型的推斷可以由以下幾個場景確定&#xff1a; 變量定義指定類型 List<String> strList new ArrayList<>();ArrayList的泛型類型是依據變量的類型確定的。 方法返回值確定 Overridepublic Function<List<I…

Deep Research:開啟深度研究的智能新時代

在當今信息爆炸的時代&#xff0c;人們面臨著海量的信息&#xff0c;無論是專業人士還是普通消費者&#xff0c;都迫切需要一種高效、精準的方式來獲取和分析信息。OpenAI 推出的 Deep Research&#xff0c;宛如一顆璀璨的新星&#xff0c;在知識的海洋中為我們導航&#xff0c…