linux的任务调度机制太高深了,目前只能做到会用这三种结构。但具体什么情况哪种性能更高却没法详细的总结下来,还需多做项目多积累啊。。。。linux是个坑。。。本篇仅记录下
tasklet
- 结构体定义
struct my_bus {
... ...
struct tasklet_struct run_tasklet;
};
- tasklet待执行的函数
void exec_tasklet(void *data){
struct my_bus *bus_if = (struct my_bus *)data;
do{
... ...
if(退出条件)
break;
}while(1);
}
- 初始化tasklet
struct my_bus *bus_if;
... ...
tasklet_init(&bus_if->run_tasklet,
(void(*)(unsigned long))exec_tasklet,
(unsigned long)bus_if);
- 停止tasklet
struct my_bus *bus_if;
... ...
tasklet_kill(&bus_if->run_tasklet);
- 调度tasklet
struct my_bus *bus_if;
... ...
tasklet_schedule(&bus_if->run_tasklet);
tasklet特点:
- 可响应中断
- 不可睡眠或阻塞
- 在软中断上实现的
- 同一个tasklet不可在多个CPU上运行
- 执行的操作是原子的
- 同一个tasklet只能在最初被提交的CPU上运行
kthread
- 结构体定义
struct my_bus {
... ...
struct completion run_trgg;//这里用了completion机制
struct task_struct *run_thread;
};
如果线程不需要频繁调用的话,或是会有线程休眠的情况,则用schedule_timeout等函数令线程进入休眠状态后,若需要调用时再wake_up_process唤醒该线程。
若是频繁用到该线程,则可用completion机制来实现调用。即线程状态一直处于running,内部函数用while(1)保证一直循环运行,但是真正对处理函数的调用要等待complete信号被触发以后才执行。
- kthread待执行的函数
void exec_thread(void *data){
struct my_bus *bus_if = (struct my_bus *)data;
struct sched_param param = { .sched_priority = 1 };
param.sched_priority = ...;//值越高优先级越高
sched_setscheduler(current, SCHED_FIFO, ¶m);//优先级有SCHED_OTHER、SCHED_RR、SCHED_FIFO
while (1) {
if(kthread_should_stop()) {
printk("run_thread stop\n");
break;
}
if (!wait_for_completion_interruptible(&bus_if->run_trgg)) {
if(bus_if->state == BUS_DOWN_ST)
break;
... ...//一些要运行的操作
}
}
}
RR-时间片轮转调度算法 FIFO-先来先服务调度算法
- 初始化thread和completion
struct my_bus *bus_if;
... ...
init_completion(&bus_if->run_trgg);
bus_if->run_thread= kthread_run(exec_thread, (void *)bus_if, "my_thread");
- 停止thread
struct my_bus *bus_if;
... ...
if (bus_if->run_thread) {
complete(&bus_if->run_trgg);
kthread_stop(bus_if->run_thread);
bus_if->run_thread= NULL;
}
- 调度thread
struct my_bus *bus_if;
... ...
complete(&bus_if->run_trgg);
kthread特点:
- 是内核调度基本单位
- 只运行在内核态
- 可选择调度算法及线程优先级
workqueue
- 结构体定义
struct my_bus {
... ...
struct work_struct work;
struct workqueue_struct *wq;
};
- workqueue待执行的函数
void work_queue_task(struct work_struct *mywork){
... ...
while (1) {
if(退出条件)
break;
}
}
- 初始化work和workqueue
struct my_bus *bus_if;
... ...
INIT_WORK(&bus_if->work, work_queue_task);
bus_if->wq= create_singlethread_workqueue("my_wq");
- workqueue释放
struct my_bus *bus_if;
... ...
memset(bus_if, 0, sizeof(*bus_if));
- 调度workqueue
struct my_bus *bus_if;
... ...
queue_work(bus_if->wq, &bus_if->work);
workqueue特点:
- 允许休眠
- 系统负载大时,worker_thread(为处理工作队列调度的线程)会自己降低优先级,会延迟工作队列执行的操作
- 可将任务推后,交给一个内核线程执行