linux创建线程_创建Linux内核线程

f148ff2eac530e91d395a89d12900701.png

线程(Thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每个线程并行执行不同的任务。

很多时候会需要在后台执行一些任务,比如做一个需要实时监控某个模块状态的debug功能,这种任务可以通过内核线程实现。

头文件

//wake_up_process()#include //kthread_create(), kthread_run()#include //IS_ERR()、PTR_ERR()#include 

操作线程的步骤:

1.创建线程kthread_create

2.唤醒线程wake_up_process

3.结束线程kthread_stop

*另外Linux也提供了接口kthread_run将1和2整合成一个步骤。

创建线程kthread_create

kthread_create是kthread_create_on_node的宏定义,创建线程后不会马上运行,其源码如下:

#define kthread_create(threadfn, data, namefmt, arg...) \    kthread_create_on_node(threadfn, data, NUMA_NO_NODE, namefmt, ##arg)

kthread_create_on_node的定义在文件kernel/kthread.c中,原型如下:

__printf(4, 5)struct task_struct *kthread_create_on_node(              int (*threadfn)(void *data),              void *data,              int node,              const char namefmt[], ...);

参数说明

threadfn:线程函数,即开启线程后需要call的API;

data:线程函数的形参,可以是NULL;

namefmt:线程名称;

返回值:线程指针strcut task_struct *;

唤醒线程wake_up_process

使用kthread_create创建线程后,需要将返回值

(struct task_struct *)作为参数传入wake_up_process()将线程唤醒,线程才会跑起来,原型:

extern int wake_up_process(struct task_struct *tsk);

创建并运行线程kthread_run

kthread_run是将kthread_create以及wake_up_process整合的宏定义,创建线程并运行,源码如下:

#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;                     \})

结束线程kthread_stop

将创建线程时返回的线程指针(struct task_struct *)作为参数传入kthread_stop(),设置结束标志should_stop,原型:

int kthread_stop(struct task_struct *k);

在线程中用到的其他API

set_freezable()//将线程设置成可冻结,如果系统会休眠,则需要使用kthread_should_stop()//检查线程的结束标志should_stop并返回set_current_state()//设置线程任务的当前状态,参数宏定义在头文件include/linux/sched.h中

创建线程实例

LunuxMemo_kthread.c

#include #include #include   //wake_up_process()#include //kthread_create(), kthread_run()#include     //IS_ERR()、PTR_ERR()#define CREATE_KTHREAD  1#define STOP_KTHREAD    0//kthread taskvoid LinuxMemo_kthread_task(void){    printk(KERN_EMERG "Plz Follow Wechat Account: LinuxMemo\n");    /*     * Add YOUR code here     */}//kthread functionint LinuxMemo_thread_func(void *data){    char *name = (char *)data;    //name = "LinuxMemo"    printk(KERN_EMERG "Plz Follow Wechat Account: %s\n", name);    set_freezable(); //set kthread freezable    while (!kthread_should_stop())    {        LinuxMemo_kthread_task();    }    return 0;}//Create or stop a kthreadint LinuxMemo_kthread_set(int set){    char *name = "LinuxMemo";    static struct task_struct *LinuxMemo_kthread;    if (CREATE_KTHREAD == set)    {        //create and wake up a kthread        LinuxMemo_kthread = kthread_create(LinuxMemo_thread_func, (void *)name, "LinuxMemo_kthread");        if (IS_ERR(LinuxMemo_task))        {            printk(KERN_EMERG "[%s] create LinuxMemo_kthread error\n", __func__);            err = PTR_ERR(LinuxMemo_kthread);            LinuxMemo_kthread = NULL;            return err;        }        wake_up_process(LinuxMemo_task);        printk(KERN_EMERG "[%s] LinuxMemo_kthread start\n", __func__);    }    else if (STOP_KTHREAD == set)    {        if (LinuxMemo_kthread)        {            //Stop a kthread            if (0 == kthread_stop(LinuxMemo_kthread))            {                printk(KERN_EMERG "[%s] LinuxMemo_kthread stop\n", __func__);            }            else            {                printk(KERN_EMERG "[%s] LinuxMemo_kthread stop error\n", __func__);            }            LinuxMemo_task = NULL;        }    }    return 0;}

654ec4b8bcae6448f6db8d472d2a43f1.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值