Linux内核线程

简介: Linux 内核线程(KERNEL THREAD)完全独立运行在内核空间,并且不能被切换到用户空间运行,也没有独立内核地址空间。除此之外,与普通的线程一样,可以被调度和抢占。

一:内核线程简介

Linux 内核线程(KERNEL THREAD)完全独立运行在内核空间,并且不能被切换到用户空间运行,也没有独立内核地址空间。除此之外,与普通的线程一样,可以被调度和抢占。


二:头文件介绍


#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/thread.h>


/

三:实现过程


1). kthread_create 函数用于创建一个内核线程,当时该内核线程并不会马上启动,需要调用wake_up_process启动线程。相关函数详情如下所示。

 #define kthread_create(threadfn, data, namefmt, arg...) \
     kthread_create_on_node(threadfn, data, -1, namefmt, ##arg)
/**
 * kthread_create_on_node - create a kthread.
 * @threadfn: the function to run until signal_pending(current).
 * @data: data ptr for @threadfn.
 * @node: memory node number.
 * @namefmt: printf-style name for the thread.
 *
 * Description: This helper function creates and names a kernel
 * thread.  The thread will be stopped: use wake_up_process() to start
 * it.  See also kthread_run().
 *
 * If thread is going to be bound on a particular cpu, give its node
 * in @node, to get NUMA affinity for kthread stack, or else give -1.
 * When woken, the thread will run @threadfn() with @data as its
 * argument. @threadfn() can either call do_exit() directly if it is a
 * standalone thread for which no one will call kthread_stop(), or
 * return when 'kthread_should_stop()' is true (which means
 * kthread_stop() has been called).  The return value should be zero
 * or a negative error number; it will be passed to kthread_stop().
 *
 * Returns a task_struct or ERR_PTR(-ENOMEM).
 */
struct task_struct *kthread_create_on_node(int (*threadfn)(void *data),
                       void *data,
                       int node,
                       const char namefmt[],
                       ...)


2). kthread_run 创建内核函数并启动,函数原型如下所示。


/**
 * kthread_run - create and wake a thread.
 * @threadfn: the function to run until signal_pending(current).
 * @data: data ptr for @threadfn.
 * @namefmt: printf-style name for the thread.
 *
 * Description: Convenient wrapper for kthread_create() followed by
 * wake_up_process().  Returns the kthread or ERR_PTR(-ENOMEM).
 */
#define kthread_run(threadfn, data, namefmt, ...)               \
({                                       \
    struct task_struct *__k                           \
        = kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \
    if (!IS_ERR(__k))                           \
        wake_up_process(__k);                       \
    __k;                                   \
})


3). kthread_stop 函数功能是结束某个线程(do_exit函数也可以实现相同功能)


/**
 * kthread_stop - stop a thread created by kthread_create().
 * @k: thread created by kthread_create().
 *
 * Sets kthread_should_stop() for @k to return true, wakes it, and
 * waits for it to exit. This can also be called after kthread_create()
 * instead of calling wake_up_process(): the thread will exit without
 * calling threadfn().
 *
 * If threadfn() may call do_exit() itself, the caller must ensure
 * task_struct can't go away.
 *
 * Returns the result of threadfn(), or %-EINTR if wake_up_process()
 * was never called.
 */
int kthread_stop(struct task_struct *k)


4). schedule_timeout 函数对当前进程进行调度,让其进入睡眠状态,让出占有的系统资源,回到超时唤醒。


/**
 * schedule_timeout - sleep until timeout
 * @timeout: timeout value in jiffies
 *
 * Make the current task sleep until @timeout jiffies have
 * elapsed. The routine will return immediately unless
 * the current task state has been set (see set_current_state()).
 *
 * You can set the task state as follows -
 *
 * %TASK_UNINTERRUPTIBLE - at least @timeout jiffies are guaranteed to
 * pass before the routine returns. The routine will return 0
 *
 * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
 * delivered to the current task. In this case the remaining time
 * in jiffies will be returned, or 0 if the timer expired in time
 *
 * The current task state is guaranteed to be TASK_RUNNING when this
 * routine returns.
 *
 * Specifying a @timeout value of %MAX_SCHEDULE_TIMEOUT will schedule
 * the CPU away without a bound on the timeout. In this case the return
 * value will be %MAX_SCHEDULE_TIMEOUT.
 *
 * In all cases the return value is guaranteed to be non-negative.
 */
signed long __sched schedule_timeout(signed long timeout)


四:注意事项


(1)在调用kthread_stop函数时,线程函数不能已经运行结束。否则,kthread_stop函数会一直进行等待。


(2)线程函数必须能让出CPU,以便能运行其他线程。同时线程函数也必须能重新被调度运行。在例子程序中,这是通过schedule_timeout()函数完成的。


五:性能测试


可以使用top命令来查看线程(包括内核线程)的CPU利用率。


命令如下:


top –p 线程号可以使用下面命令来查找线程号:


ps aux|grep 线程名可以用下面的命令显示所有内核线程:


ps afx注:线程名由kthread_create函数的第三个参数指定 在分析usb_hub_init()的代码的时候,忽略掉了一部份. 代码片段如下所示:


int usb_hub_init(void) 
{ 
……
khubd_task = kthread_run(hub_thread, NULL,"khubd"); 
……
} 


Kthread_run() 是kernel中用来启动一个新kernel线程的接口,它所要执行的函数就是后面跟的第一个参数.在这里,也就是hub_thread().另外,顺带提一句,要终止kthread_run()创建的线程,可以调用kthread_stop().

相关文章
|
15天前
|
存储 Linux 调度
深入理解Linux内核:从用户空间到内核空间的旅程
【8月更文挑战第4天】在这篇文章中,我们将探索Linux操作系统的核心—内核。通过了解内核如何管理硬件资源,以及它是如何在用户空间和内核空间之间架起桥梁的,我们可以更好地理解操作系统的工作原理。本文将介绍一些关键概念,并通过代码示例来揭示这些概念是如何在实际中应用的。无论你是开发者、系统管理员还是对操作系统感兴趣的爱好者,这篇文章都将为你提供一个深入了解Linux内核的机会。让我们开始这段旅程吧!
|
14天前
|
算法 Unix Linux
linux线程调度策略
linux线程调度策略
26 0
|
2月前
|
Linux API 调度
技术笔记:Linux内核跟踪和性能分析
技术笔记:Linux内核跟踪和性能分析
|
1天前
|
Ubuntu Linux Windows
如何在WSL中的ubuntu编译Linux内核并且安装使用ebpf?
请注意,在WSL1中可能会由于内核架构限制而无法成功进行以上过程,WSL2对于Linux内核的完整支持更为合适。此外,部分步骤可能因不同的Linux发行版或内核版本而异。
8 4
|
21小时前
|
Linux 开发者
Linux的诞生:Linus Torvalds的“惊天一敲”与Linux内核的“首秀”
在科技界璀璨星辰中,Linus Torvalds以一次“惊天一敲”悄然点燃了革命之火——Linux就此诞生。1991年,不满现状的Linus决定创造更好的操作系统,这一敲不仅开启了个人传奇,更奏响了技术革新的序章。他将Linux内核低调发布网络,随即吸引了全球开发者的目光与贡献,使之迅速成长为开源世界的巨星。Linus的故事告诉我们:伟大创举常源于微小想法,也许下一个改变世界的“一敲”就出自你手。
12 1
|
15天前
|
Ubuntu Linux 开发工具
深入探索Linux内核模块编程
【8月更文挑战第4天】在这篇文章中,我们不仅将探讨Linux内核模块的基础知识,还将通过一个实际的例子来展示如何编写一个简单的内核模块。我们将从理论出发,逐步过渡到动手实践,最终实现一个可以在Linux系统上运行的模块。文章的目标是为读者提供足够的信息和知识,以便他们能够自己编写内核模块,从而对操作系统的内部工作原理有更深入的了解。
|
17天前
|
Linux
Linux系统如何查看版本信息,内核、发行版、cpu、所有版本
Linux系统如何查看版本信息,内核、发行版、cpu、所有版本
|
17天前
|
算法 Linux 调度
探索进程调度:Linux内核中的完全公平调度器
【8月更文挑战第2天】在操作系统的心脏——内核中,进程调度算法扮演着至关重要的角色。本文将深入探讨Linux内核中的完全公平调度器(Completely Fair Scheduler, CFS),一个旨在提供公平时间分配给所有进程的调度器。我们将通过代码示例,理解CFS如何管理运行队列、选择下一个运行进程以及如何对实时负载进行响应。文章将揭示CFS的设计哲学,并展示其如何在现代多任务计算环境中实现高效的资源分配。
|
14天前
|
存储 Unix Linux
揭秘Linux硬件组成:从内核魔法到设备树桥梁,打造你的超级系统,让你的Linux之旅畅通无阻,震撼体验来袭!
【8月更文挑战第5天】Linux作为顶级开源操作系统,凭借其强大的功能和灵活的架构,在众多领域大放异彩。本文首先概述了Linux的四大核心组件:内核、Shell、文件系统及应用程序,并深入探讨了内核的功能模块,如存储、CPU及进程管理等。接着介绍了设备树(Device Tree),它是连接硬件与内核的桥梁,通过DTS/DTB文件描述硬件信息,实现了跨平台兼容。此外,还简要介绍了Linux如何通过本地总线高效管理硬件资源,并阐述了文件系统与磁盘管理机制。通过这些内容,读者可以全面了解Linux的硬件组成及其核心技术。
29 3
|
14天前
|
缓存 Linux C语言
Linux线程是如何创建的
【8月更文挑战第5天】线程不是一个完全由内核实现的机制,它是由内核态和用户态合作完成的。