源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

基于内核线程的创建、使用和退出以及延时宏的补充说明介绍

  • 时间:2020-02-26 02:23 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:基于内核线程的创建、使用和退出以及延时宏的补充说明介绍
[b]相关函数:[/b] [b]kthread_create():创建内核线程 [/b]
[u]复制代码[/u] 代码如下:
struct task_struct *kthread_create(int (*threadfn)(void *data), void *data, const char namefmt[], ...);  kernel thread可以用kernel_thread创建,但是在执行函数里面必须用daemonize释放资源并挂到init下,还需要用completion等待这一过程的完成。为了简化操作,定义了kthread_create。
线程创建后,不会马上运行,而是需要将kthread_create() 返回的task_struct指针传给wake_up_process(),然后通过此函数运行线程。   [b]kthread_run():创建并启动线程的函数。 [/b]
[u]复制代码[/u] 代码如下:
struct task_struct *kthread_run(int (*threadfn)(void *data),void *data,const char *namefmt, ...);它实际上是个宏,由kthread_create()和wake_up_process()组成。
它实际上是个宏,由kthread_create()和wake_up_process()组成。
[u]复制代码[/u] 代码如下:
#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():通过发送信号给线程,使之退出。
[u]复制代码[/u] 代码如下:
int kthread_stop(struct task_struct *thread);
线程一旦启动起来后,会一直运行,除非该线程主动调用do_exit函数,或者其他的进程调用kthread_stop函数,结束线程的运行。 但如果线程函数正在处理一个非常重要的任务,它不会被中断的。当然如果线程函数永远不返回并且不检查信号,它将永远都不会停止。 同时,在调用kthread_stop函数时,线程函数不能已经运行结束。否则,kthread_stop函数会一直进行等待。   内核线程的一般框架 int threadfunc(void *data){         …         while(1){                set_current_state(TASK_UNINTERRUPTIBLE);                if(kthread_should_stop()) break;                if(){//条件为真                       //进行业务处理                }                else{//条件为假                       //让出CPU运行其他线程,并在指定的时间内重新被调度                       schedule_timeout(HZ);                }         }         …         return 0; }   线程相关测试命令   可以使用top命令来查看线程(包括内核线程)的CPU利用率。命令如下:     top –p 线程号   可以使用下面命令来查找线程号:     ps aux|grep 线程名   示例程序:使用模块加载内核线程,实现每1s在内核中打印字符。 (makefile略去,和以前一篇博文一样的写法。)
[u]复制代码[/u] 代码如下:
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h>   //wake_up_process() #include <linux/kthread.h> //kthread_create(),kthread_run() #include <linux/err.h> //IS_ERR(),PTR_ERR() #ifndef SLEEP_MILLI_SEC #define SLEEP_MILLI_SEC(nMilliSec)\ do { \ long timeout = (nMilliSec) * HZ / 1000; \ while(timeout > 0) \ { \ timeout = schedule_timeout(timeout); \ } \ }while(0); #endif static struct task_struct *my_task = NULL; static int my_kthread(void *data)  {      char *mydata = kmalloc(strlen(data)+1,GFP_KERNEL);     memset(mydata,'\0',strlen(data)+1);     strncpy(mydata,data,strlen(data));     while(!kthread_should_stop())     {         SLEEP_MILLI_SEC(1000);         printk("%s\n",mydata);     }     kfree(mydata);     return 0; }  static int __init kernel_thread_init(void) {     int err;     printk(KERN_ALERT "Kernel thread initalizing...\n");     my_task = kthread_create(my_kthread,"hello world","mythread");     if(IS_ERR(my_task)){         printk("Unable to start kernel thread./n");         err = PTR_ERR(my_task);         my_task = NULL;         return err;     }     wake_up_process(my_task);     return 0;#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h>   //wake_up_process() #include <linux/kthread.h> //kthread_create(),kthread_run() #include <linux/err.h> //IS_ERR(),PTR_ERR() #ifndef SLEEP_MILLI_SEC #define SLEEP_MILLI_SEC(nMilliSec)\ do { \ long timeout = (nMilliSec) * HZ / 1000; \ while(timeout > 0) \ { \ timeout = schedule_timeout(timeout); \ } \ }while(0); #endif static struct task_struct *my_task = NULL; static int my_kthread(void *data)  {      char *mydata = kmalloc(strlen(data)+1,GFP_KERNEL);     memset(mydata,'\0',strlen(data)+1);     strncpy(mydata,data,strlen(data));     while(!kthread_should_stop())     {         SLEEP_MILLI_SEC(1000);         printk("%s\n",mydata);     }     kfree(mydata);     return 0; }  static int __init kernel_thread_init(void) {     int err;     printk(KERN_ALERT "Kernel thread initalizing...\n");     my_task = kthread_create(my_kthread,"hello world","mythread");     if(IS_ERR(my_task)){         printk("Unable to start kernel thread./n");         err = PTR_ERR(my_task);         my_task = NULL;         return err; } static void __exit kernel_thread_exit(void) {     if(my_task){         printk(KERN_ALERT "Cancel this kernel thread.\n");         kthread_stop(my_task);         printk(KERN_ALERT "Canceled.\n");         } } module_init(kernel_thread_init); module_exit(kernel_thread_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("anonymous");
[b]补充说明:[/b]   这个延时宏在一些情况下会造成内核线程CPU占用率过高的情况。根据对schedule_timeout()源码的分析,它只是周期使线程成为TASK_RUNNING状态,这个线程并没有真正的睡眠。解决办法:在while循环中的起始处加入set_current_state(TASK_INTERRUPTIBLE)即可。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部