1.头文件
#include <linux/sched.h>   //wake_up_process()
#include <linux/kthread.h> //kthread_create()、kthread_run()
#include <err.h> //IS_ERR()、PTR_ERR()2.实现(kthread_create 与kthread_run区别)
linux内核创建线程的方法实质上只有一个:kthread_create,kthread_run是kthread_create的宏罢了;但这个宏却有一定的意义,正如其名一样:
kthread_create:创建线程。线程创建后,不会马上运行,而是需要将kthread_create() 返回的task_struct指针传给wake_up_process(),然后通过此函数运行线程。
kthread_run :创建并启动线程的函数:
2.1创建线程
在模块初始化时,可以进行线程的创建。使用下面的函数和宏定义:
struct task_struct *kthread_create(int (*threadfn)(void *data),
void *data,
const char namefmt[], ...);
#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; \
})
例如:
static struct task_struct *test_task;
static int test_init_module(void)
{
int err;
test_task = kthread_create(test_thread, NULL, "test_task");
if(IS_ERR(test_task)){
printk("Unable to start kernel thread. ");
err = PTR_ERR(test_task);
test_task = NULL;
return err;
}
wake_up_process(test_task);
return ;
}
module_init(test_init_module);
2.2线程函数
在线程函数里,完成所需的业务逻辑工作。主要框架如下所示:
int threadfunc(void *data){

while(){
set_current_state(TASK_UNINTERRUPTIBLE);
if(kthread_should_stop()) break;
if(){//条件为真
//进行业务处理
}
else{//条件为假
//让出CPU运行其他线程,并在指定的时间内重新被调度
schedule_timeout(HZ);
}
}

return ;
}
2.3结束线程
在模块卸载时,可以结束线程的运行。使用下面的函数:
int kthread_stop(struct task_struct *k);
例如:
              static void test_cleanup_module(void)
{
if(test_task){
kthread_stop(test_task);
test_task = NULL;
}
}
module_exit(test_cleanup_module);
3.注意事项
(1) 在调用kthread_stop函数时,线程函数不能已经运行结束。否则,kthread_stop函数会一直进行等待。
(2) 线程函数必须能让出CPU,以便能运行其他线程。同时线程函数也必须能重新被调度运行。在例子程序中,这是通过schedule_timeout()函数完成的。
4.性能测试
可以使用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().

linux内核中创建线程方法的更多相关文章

  1. linux内核中创建线程方法【转】

    本文转载自:https://www.cnblogs.com/Ph-one/p/6077787.html 1.头文件 #include <linux/sched.h> //wake_up_p ...

  2. 【转】 Linux内核中读写文件数据的方法--不错

    原文网址:http://blog.csdn.net/tommy_wxie/article/details/8193954 Linux内核中读写文件数据的方法  有时候需要在Linuxkernel--大 ...

  3. linux内核中socket的创建过程源码分析(总结性质)

    在漫长地分析完socket的创建源码后,发现一片浆糊,所以特此总结,我的博客中同时有另外一篇详细的源码分析,内核版本为3.9,建议在阅读本文后若还有兴趣再去看另外一篇博文.绝对不要单独看另外一篇. 一 ...

  4. JAVA中创建线程的三种方法及比较

    JAVA中创建线程的方式有三种,各有优缺点,具体如下: 一.继承Thread类来创建线程 1.创建一个任务类,继承Thread线程类,因为Thread类已经实现了Runnable接口,然后重写run( ...

  5. Java中创建线程的三种方法以及区别

    Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例.Java可以用三种方式来创建线程,如下所示: 1)继承Thread类创建线程 2)实现Runnable接口创建线 ...

  6. 【转】Linux内核中分配4M以上大内存的方法

    在Linux内核中, kmalloc能够分配的最大连续内存为2的(MAX_ORDER-1)次方个page(参见alloc_pages函数,     "if (unlikely(order & ...

  7. JAVA中创建线程池的五种方法及比较

    之前写过JAVA中创建线程的三种方法及比较.这次来说说线程池. JAVA中创建线程池主要有两类方法,一类是通过Executors工厂类提供的方法,该类提供了4种不同的线程池可供使用.另一类是通过Thr ...

  8. 向linux内核中添加外部中断驱动模块

    本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内 ...

  9. Linux内核中的软中断、tasklet和工作队列具体解释

    [TOC] 本文基于Linux2.6.32内核版本号. 引言 软中断.tasklet和工作队列并非Linux内核中一直存在的机制,而是由更早版本号的内核中的"下半部"(bottom ...

随机推荐

  1. Lintcode: Sort Letters by Case

    Given a string which contains only letters. Sort it by lower case first and upper case second. Note ...

  2. RESTful架构详解(转)

    1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次出现在2000年Roy Fielding的 ...

  3. [Reprint]C++函数前和函数后加const修饰符区别

    c++中关于const的用法有很多,const既可以修饰变量,也可以函数,不同的环境下,是有不同的含义.今天来讲讲const加在函数前和函数后面的区别.比如: 01 #include<iostr ...

  4. Ruby操作Excel的方法与技巧大全

    测试工作中,批量的数据通常会放到excel表格中,测试输出的数据写回表格中,这样输入输出易于管理,同时清晰明了 使用ruby来操作excel文件首先需要在脚本里包含以下语句 require'win32 ...

  5. Java基础(30):String对象的常用方法与实例(String类)

    Java 中 String 类的常用方法 Ⅰ String 类提供了许多用来处理字符串的方法,例如,获取字符串长度.对字符串进行截取.将字符串转换为大写或小写.字符串分割等,下面我们就来领略它的强大之 ...

  6. 每天一个liunx命令(ubuntu)

    解压XXX.gz到另一个A文化夹: 1.切换到root权限 su 2.tar -zxvf  XXX.gz -C  A 注意: C要大些因为ubuntu区分大小写

  7. 今天遇到的一个问题(windows的ssh客户端连接不到虚拟机Ubuntu)

    今天比较郁闷,想用windows上的ssh客户端连接虚拟机中的Ubuntu. 但是死活连不上,之前是能脸上的,所以比较郁闷. 我首先在windows上ping Ubuntu的ip地址,竟然发不了数据包 ...

  8. 夺命雷公狗—angularjs—16—angularjs里面的缓存

    强大的angularjs也给我们预留了一套他的缓存机智,这样在某个程度上来说还是可以做到减轻一点服务器压力的.... <!DOCTYPE html> <html lang=" ...

  9. ASP.NET MVC (一)

    工作清闲好一段时间了,趁这段时间弄了弄PHP,做个了简单的MVC网页.玩了玩Android,弄了个拨号器,发短信的,嘿嘿,最满意的还是两天弄了个数独游戏.不务正业一个多月了,也该磨磨刀,接下来一段时间 ...

  10. 【linux】xrander/cvt自定义分辨率

    今天在虚拟机上装了一个LUbuntux64(12.10)玩,安装的时候,由于主板默认是没有开虚拟化支持,报错,改后相当的顺利.但是进入系统后,屏幕显示分辨率为800X600的,全屏的话,在大显示器上显 ...