工作项、工作队列和工作者线程
。
实际上,工作队列的本质就是将工作交给内核线程处理,因此其可以用内核线程替换。但是内核线程的创建和销毁对编程者的要求较高,而工作队列实现了内核线程的封装,,不易出错,所以我们也推荐使用工作队列。
工作队列使用相关文件:
kernel/include/linux/workqueue.h
Kernel/kernel/workqueue.c
工作队列的创建要使用工作队列,需要先创建工作项,有两种方式:
1)静态创建:
DECLARE_WORK(name,function); 定义正常执行的工作项
2)动态创建,运行时创建:
INIT_WORK(&work, new_ts_work);
INIT_DELAYED_WORK(&led_work,s0340_ledtime_scanf);
工作队列待执行的函数原型是:
typedef void(*work_func_t)(structwork_struct *work);
函数可以睡眠。需要注意的是,尽管该函数运行在进程上下文中,但它不能访问用户空间,因为内核线程在用户空间没有相关的内存映射。通常在系统调用发生时,内核会代表用户空间的进程运行,此时它才能访问用户空间,也只有在此时它才会映射用户空间的内存。
创建了工作项之后,在适当的时候可以通过下面的两种方式来提交工作项给工作者线程,通常我们使用的工作队列和工作者线程都是系统初始化时候默认创建的。
工作队列的调度运行schedule_work(&work);
delay指定的时钟节拍用完以后才会执行。
eg:
schedule_delayed_work(&kpd_backlight_work,msecs_to_jiffies(300));
默认工作队列和工作者线程创建过程events/1线程。
cpu上。
中实现。
kernel_init()–>do_basic_setup()–>init_workqueues(),该函数中创建了上面提到的默认工作队列和工作者线程。
init_workqueues()–>
–>hotcpu_notifier(workqueue_cpu_callback,0);
–>keventd_wq=create_workqueue(“events”);
cpu_chain上的所有回调函数。
这里主要关注的是函数:create_workqueue(“events”);
@kernel/include/linux/workqueue.h
__create_workqueue_key((name),(singlethread),(freezeable),(rt),/NULL,NULL)
#definecreate_workqueue(name)__create_workqueue((name),0,0,0)
#definecreate_rt_workqueue(name)__create_workqueue((name),0,0,1)
#definecreate_freezeable_workqueue(name)__create_workqueue((name),1,1,0)
#definecreate_singlethread_workqueue(name)__create_workqueue((name),1,0,0)
@kernel/kernel/workqueue.c
人生最大的错误是不断担心会犯错