Linux設備驅動器 之一 工作(worker)線程

Linux設備驅動器之一 工作線程

  • 數據結構
  • Linux APIs
    • 產生工作線程 kthread_create_worker
    • 初始化工作 kthread_init_work
    • 排隊工作 kthread_queue_work
  • 在Linux中的應用實列
    • SPI 驅動器與imx SPI
      • 任務工作線程代碼
      • 啟動任務工作線程
  • 工作線程(worker)
    • Linux管理線程

數據結構

struct kthread_worker {unsigned int        flags;raw_spinlock_t      lock;struct list_head    work_list;struct list_head    delayed_work_list;struct task_struct  *task;struct kthread_work *current_work;
};struct kthread_work {struct list_head    node;kthread_work_func_t func;struct kthread_worker   *worker;/* Number of canceling calls that are running at the moment. */int         canceling;
};struct kthread_delayed_work {struct kthread_work work;struct timer_list timer;
};

Linux APIs

產生工作線程 kthread_create_worker

struct kthread_worker *kthread_create_worker(unsigned int flags, const char namefmt[], …)

  1. unsigned int flags : 指定任務工作線程默認行為
  2. const char namefmt[] : kthread 任務工作線程的printf樣式名稱。
  3. … : 變量參數

如果成功,則返回一個指針, 它指向已產生的任務工作線程;
如果無法分配所需的結構,則返回 ERR_PTR(-ENOMEM);
如果調用者收到一個致命信號,則返回 ERR_PTR(-EINTR)。

初始化工作 kthread_init_work

kthread_init_work(work, fn)
這是一個宏定義,它初始化struct kthread_work結構變量work, 并設置fn為完成該工作的程序代碼。就是調用fn去完成需要的工作。

排隊工作 kthread_queue_work

bool kthread_queue_work(struct kthread_worker *worker, struct kthread_work *work)
功能: 排隊一個kthread_work
參數:

  1. struct kthread_worker *worker : 任務工作線程
  2. struct kthread_work *work: 需要排隊的工作

將工作排隊到工作處理器任務以進行異步執行。任務必須已使用 kthread_worker_create() 創建。如果工作已成功排隊,則返回 true;如果工作已處于掛起狀態,則返回 false。
如果工作需要由其他任務工作線程使用,請重新初始化該工作。例如,當任務工作線程停止并再次啟動時。

在Linux中的應用實列

SPI 驅動器與imx SPI

spi_init_queue調用kthread_create_worker,kthread_init_work, 去產生SPI任務工作線程,細節見下面的代碼段。

static int spi_init_queue(struct spi_controller *ctlr)
{ctlr->running = false;ctlr->busy = false;ctlr->kworker = kthread_create_worker(0, dev_name(&ctlr->dev));if (IS_ERR(ctlr->kworker)) {dev_err(&ctlr->dev, "failed to create message pump kworker\n");return PTR_ERR(ctlr->kworker);}kthread_init_work(&ctlr->pump_messages, spi_pump_messages);/** Controller config will indicate if this controller should run the* message pump with high (realtime) priority to reduce the transfer* latency on the bus by minimising the delay between a transfer* request and the scheduling of the message pump thread. Without this* setting the message pump thread will remain at default priority.*/if (ctlr->rt)spi_set_thread_rt(ctlr);return 0;
}

imx SPI 驅動器支持NXP i.MX 8M Nano。
下列的流程圖描繪了imx SPI 驅動器如何調用spi_init_queue去初始化任務工作線程。

Created with Rapha?l 2.3.0 spi_imx_probe imx 專用初始化 spi_bitbang_start 結束
Created with Rapha?l 2.3.0 spi_bitbang_start spi_bitbang_init bitbang初始化成功 ? spi_register_master 結束 yes no

spi_register_master 由下列的宏定義

#define spi_register_master(_ctlr)  spi_register_controller(_ctlr)
Created with Rapha?l 2.3.0 spi_register_controller spi_controller_initialize_queue 結束
Created with Rapha?l 2.3.0 spi_controller_initialize_queue spi_init_queue 結束

任務工作線程代碼

static void spi_pump_messages(struct kthread_work *work)

Created with Rapha?l 2.3.0 spi_pump_messages __spi_pump_messages 結束
Created with Rapha?l 2.3.0 __spi_pump_messages 任務工作線程空閑 ? prepare_transfer_hardware, 來自SPI控制結構 prepare_message, 來自SPI控制結構 spi_map_msg, 來自SPI控制結構 transfer_one_message, 來自SPI控制結構 結束 kthread_queue_work yes no

如果SPI任務工作線程忙,則調用kthread_queue_work,將任務工作加入到等待隊列。

啟動任務工作線程

工作線程(worker)

int kthread_worker_fn(void *worker_ptr)
{struct kthread_worker *worker = worker_ptr;struct kthread_work *work;/** FIXME: Update the check and remove the assignment when all kthread* worker users are created using kthread_create_worker*() functions.*/WARN_ON(worker->task && worker->task != current);worker->task = current;if (worker->flags & KTW_FREEZABLE)set_freezable();repeat:set_current_state(TASK_INTERRUPTIBLE);  /* mb paired w/ kthread_stop */if (kthread_should_stop()) {__set_current_state(TASK_RUNNING);raw_spin_lock_irq(&worker->lock);worker->task = NULL;raw_spin_unlock_irq(&worker->lock);return 0;}work = NULL;raw_spin_lock_irq(&worker->lock);if (!list_empty(&worker->work_list)) {work = list_first_entry(&worker->work_list,struct kthread_work, node);list_del_init(&work->node);}worker->current_work = work;raw_spin_unlock_irq(&worker->lock);if (work) {kthread_work_func_t func = work->func;__set_current_state(TASK_RUNNING);trace_sched_kthread_work_execute_start(work);work->func(work);/** Avoid dereferencing work after this point.  The trace* event only cares about the address.*/trace_sched_kthread_work_execute_end(work, func);} else if (!freezing(current))schedule();try_to_freeze();cond_resched();goto repeat;
}                                                                                                        

這個線程的流程圖如下

Created with Rapha?l 2.3.0 開始 設置當前任務為可中斷 任務工作線程是否應該繼續? 從任務鏈表取下一個任務 有下一個任務工作嗎 調用任務工作的回調函數 嘗試凍結當前線程 重新規劃線程調用 yes no yes no

它檢查這個任務線程的任務工作鏈表,如果非空,那么就從任務工作鏈表上取下一個任務工作 并運行它的回調函數。這個回調函數在任務工作初始化是設置。
從這個程序段看出,任務工作一定要初始化。

Linux管理線程

Linux系統初始時,產生了一個工作線程的管理線程,這里稱其為任務線程產生的監視線程。

kthread_create_worker產生一個struct kthread_create_info變量,并將這個變量加入到一個待產生線程鏈表中,這個鏈表的表頭是kthread_create_list

監視線程監視這個待產生線程鏈表,一旦新的變量加入這個鏈表,這個監視線程就產生一個新的任務工作(worker)線程。

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

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

相關文章

14-44 劍和詩人18 - 你想怎么應用 RAG 與微調

?????? 要充分發揮 LLM 的潛力,需要在檢索增強生成 (RAG) 和微調之間選擇正確的技術。 讓我們研究一下何時針對 LLM、較小模型和預訓練模型使用 RAG 而不是微調。我們將介紹: LLM 和 RAG 的簡要背景RAG 相對于微調 LLM 的優勢何時針對不同模型大…

AI集成工具平臺一站式體驗,零門檻使用國內外主流大模型

目錄 0 寫在前面1 AI藝術大師1.1 繪畫制圖1.2 智能作曲 2 AI科研助理2.1 學術搜索2.2 自動代碼 3 AI智能對話3.1 聊天機器人3.2 模型競技場 4 特別福利 0 寫在前面 人工智能大模型浪潮滾滾,正推動著千行百業的數智化進程。隨著技術演進,2024年被視為是大…

linux修改內核實現禁止被ping

概述 Linux默認允許被ping。其主要決定因素為: 內核參數防火墻(iptables/firewall) 以上的決定因素是與的關系,即需要均滿足。 因此,修改linux禁被ping有以上兩種方法可以實現。 修改內核文件使禁ping 1. 臨時生…

服務預約自動化:智能機器人引領預約新潮流

在數字化時代,服務預約的需求日益增長,智能機器人以其自動化和智能化的特性,正在重塑服務預約的流程。 一、服務預約的現代挑戰 服務預約流程面臨的挑戰包括用戶操作復雜、等待時間長、個性化服務難以滿足等。 二、智能機器人的優勢 智能…

Perl 語言入門:編寫并執行你的第一個腳本

摘要 Perl 是一種高級、通用的、解釋型、動態編程語言,以其強大的文本處理能力而聞名。本文將指導初學者如何編寫和執行他們的第一個 Perl 腳本,包括 Perl 的基本概念、腳本的基本結構、運行 Perl 腳本的方法以及一些簡單的 Perl 語法。 引言 Perl&am…

保健品商城小程序模板源碼

保健品商城小程序模板源碼 簡潔通用的保健品,健康生活,零售商品,電子商務微信小程序前端模板下載。包含:主頁、購物車、客服、個人中心、我的訂單、商品詳情、我的錢包、設置等等。 保健品商城小程序模板源碼

定制化模型煉金術:Mojo模型與自定義訓練循環的動態融合

定制化模型煉金術:Mojo模型與自定義訓練循環的動態融合 在機器學習領域,模型訓練循環是構建智能系統的核心過程。Mojo模型,作為H2O.ai提供的一種模型部署格式,主要用于模型的序列化和預測。雖然Mojo模型本身不支持自定義訓練循環…

web安全基礎名詞概念

本節內容根據小迪安全講解制作 第一天 域名: 1.1什么是域名? 網域名稱(英語:Domain Name,簡稱:Domain),簡稱域名、網域,是由一串用點分隔的字符組成的互聯網上某一臺計算機或計算機組的名稱&a…

celery執行任務報錯ValueError: not enough values to unpack

背景 在做用戶注冊模塊的時候需要對手機號驗證的過程進行優化,目前想到的方式是通過celeryrabbitmq的方式進行異步處理,選擇使用celery是因為使用方便、性能好、可分布式部署。 環境信息 目前使用地win11容器化啟動 rabbitmq:3.13.2 python:3.6.8 cel…

OEACLE怎么實現AES加密解密

在Oracle數據庫中實現AES加密解密,通常會使用Oracle提供的DBMS_CRYPTO包。DBMS_CRYPTO是一個強大的PL/SQL包,用于加密和解密數據,支持多種加密算法,包括AES。以下是實現AES加密解密的具體步驟和示例: 一、確保權限 首…

高薪程序員必修課-JVM創建對象時如何解決多線程內存搶占問題

前言 在JVM中,堆的內存分配過程涉及到線程安全性的保障,具體來說涉及到對象的內存分配時,并不是簡單的搶占式分配,而是通過一些機制來保證線程安全和高效的內存管理。下面解釋一下JVM是如何設計來保證線程安全的: 內存…

Oracle怎么實現RSA加密解密

Oracle數據庫實現RSA加密解密通常需要通過Java編寫的存儲過程來完成,因為Oracle自身并不直接支持RSA加密的原生函數。以下是實現RSA加密解密的大致步驟和考慮因素: 一、準備Java類 編寫Java類: 創建一個Java類(如RSACrypto&…

STA:延遲為什么會有負值?

我正在「拾陸樓」和朋友們討論有趣的話題,你?起來吧? 拾陸樓知識星球入口 相關文章鏈接: STA:串擾延遲分析 STA:CRPR悲觀路徑移除 這個問題就是典型的SI問題,受SI影響,與hold 分析而言data…

AI Native 入門案例教程

環境準備 1. 安裝 AI Native 首先,需要安裝 AI Native。可以通過 pip 安裝: pip install ainative2. 安裝 TensorFlow AI Native 是基于 TensorFlow 的,因此需要安裝 TensorFlow。可以通過 pip 安裝: pip install tensorflow…

Dify v0.6.9源碼部署

一.前置條件 克隆Dify v0.6.9代碼: git clone https://github.com/langgenius/dify.git在啟用業務服務之前,需要先部署 PostgresSQL / Redis / Weaviate(如果本地沒有的話),可以通過以下命令啟動: cd do…

Data-Juicer:阿里巴巴榮譽出品的大模型數據清洗框架

Diffusion Models專欄文章匯總:入門與實戰 前言:如何優雅地進行大規模數據清洗是一門藝術,特別對于大模型,數據的質量是決定模型成功最關鍵的因素之一。阿里巴巴最近開源了一項專門針對大語言模型和視頻生成大模型的數據清洗框架&…

短信群發平臺適用于哪些行業?

短信群發平臺作為一種高效、快速且成本相對較低的通信方式,適用于多個行業。以下是一些主要適用行業的概述: 1. 零售與電商行業 應用場景:零售和電商企業可以利用短信群發進行新品推廣、促銷信息發布、訂單狀態更新、物流跟蹤通知等。 2. 金…

redis并發、穿透、雪崩

Redis如何實現高并發 首先是單線程模型:redis采用單線程可以避免多線程下切換和競爭的開銷,提高cpu的利用率,如果是多核cpu,可以部署多個redis實例。基于內存的數據存儲:redis將數據存儲在內存中,相比于硬…

wireshark抓取Chrome瀏覽器quic協議的明文包

wireshark版本:Version 4.2.5 (v4.2.5-0-g4aa814ac25a1). 1.chromium瀏覽器啟用quic: chrome://flags/#enable-quic 2.windows添加環境變量 SSLKEYLOGFILED:\sslkeylogfile.log 3.配置wireshark,編輯->首選項->Protocls->TLS:(Pre)-…

MyBatis(30)如何在 MyBatis 中使用 XML 和注解混合配置方式

在MyBatis中,你可以靈活地選擇XML配置方式、注解方式,或者將這兩種方式混合使用來配置你的映射器(Mapper)。使用混合配置方式,你可以結合兩者的優勢,例如,利用XML配置復雜查詢和動態SQL&#xf…