内核线程的简单使用

    内核线程是工作在内核空间的,不属于任何一个进程,可以发生睡眠。内核线程的相关代码在:include/linux/kthread.h , kernel/kthread.c

    1. 创建并启动一个内核线程

struct task_struct *kthread_create(int (*threadfn)(void *data),
                               void *data,
                               const char namefmt[], ...);
 
/**
 * 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;                                                     \
})

    其中kthread_create()只是创建一个内核线程,但并没有启动,需要调用wake_up_process()来启动线程,所以内核又帮我们定义了一个宏kthread_run来帮我们搞定。内核线程创建成功后,会返回一个struct task_struct对象指针,方便我们的后续操作。

    2. 关闭一个内核线程:

int kthread_stop(struct task_struct *k);

    这个调用是会阻塞等待,直到内核线程k退出为止。原因为因为此函数内部会调用wait_for_completion()的方法(通过等待队列来实现),阻塞等待内核线程自身的退出。

    3.内核线程函数,如何判断自身需要退出:

 int kthread_should_stop(void);

如果该内核线程已经被设置stop标志了,则会返回1,否则返回0。

    4. 一个简单的例子:

    在模块初始化的时候创建一个内核线程,此内核线程的功能是每隔2秒中打印一条信息。当我们卸载模块的时候,会关闭该内核线程。

#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/delay.h>
 
 
#define ENTER() printk(KERN_DEBUG "%s() Enter", __func__)
#define EXIT() printk(KERN_DEBUG "%s() Exit", __func__)
#define ERR(fmt, args...) printk(KERN_ERR "%s()-%d: " fmt "\n", __func__, __LINE__, ##args)
#define DBG(fmt, args...) printk(KERN_DEBUG "%s()-%d: " fmt "\n", __func__, __LINE__, ##args)
 
MODULE_LICENSE("GPL");
 
static int demo_thr(void *data)
{
    ENTER();
    while (!kthread_should_stop()) {
        DBG("kthread is running");
        msleep_interruptible(2000);
    }
 
    EXIT();
    return 0;
}
 
static struct task_struct *thr = NULL;
 
static __init int kthread_demo_init(void)
{
    ENTER();
 
    thr = kthread_run(demo_thr, NULL, "kthread-demo");
    if (!thr) {
        ERR("kthread_run fail");
        return -ECHILD;
    }
 
    EXIT();
    return 0;
}
 
static __exit void kthread_demo_exit(void)
{
    ENTER();
    if (thr) {
        DBG("kthread_stop");
        kthread_stop(thr);
        thr = NULL;
    }
   
    EXIT();
}
 
module_init(kthread_demo_init);
module_exit(kthread_demo_exit);










转载于:https://my.oschina.net/kaedehao/blog/621810

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值