tasklets和work queues介绍及实例

本文介绍了Linux内核中用于推迟执行任务的tasklets和work queues,探讨它们的历史、API、实例及区别。tasklets在中断上下文执行,适合简单快速的任务,而work queues在内核进程上下文执行,支持睡眠,适用于更复杂的任务。
摘要由CSDN通过智能技术生成

一点历史

本文将介绍在内核中推迟执行任务的几种方法. 尽管这些方法只适用于Linux内核, 但其背后的思想在架构方面依然有用. 比如 你可以在传统嵌入式系统中实现这些方法, 来取代原有的任务调度方法.
在深入内核下半部的方法之前, 先介绍下背景知识. 首先要知道, 硬件事件(如网卡收到数据包)会使操作系统中断, 这个中断会引起一系列的处理任务. 一些任务在中断上下文中处理掉, 剩下的在内核上下文中处理. 本文介绍的是
那么问题来了, 中断上下文中应该处理掉多少任务呢? 在中断上下文中是禁中断的,这期间其它的硬件事件是不能及时处理的, 因此, 中断上下文要处理的任务越少越好, 而把大量的工作推迟执行, 放到内核上下文, 这意味着可以及时处理硬件中断, 这里的任务分成了两部分处理, 前者叫上半部(top half), 后者也是本文的重点, 叫做下半部(bottom half), 这些概念是从老美翻译过来的, 先入为主, 否则叫前半部和后半部可能更容易理解些. 总之, 同样的任务, 更短的中断处理时间可以带来更好的性能.
一点历史
从内核2.3开始, 静态定义了32个下半部集合, 这个数组在编译时就确定了, 相关代码在./kernel/softirq.c中, 这就是是软中断. 同时内核2.3也引入了tasklet, 它是基于软中断的, 允许动态创建延时任务. 接着在内核2.5中引入了工作队列(Work queues, ./include/linux/workqueue.h). 工作队列允许将中断上下文处理的任务推迟到内核进程上下文执行.
接下来我们看下 tasklets和work queues 是怎样动态创建的

tasklet

/∗ 声明 Tasklet (下半部) ∗/
void tasklet_function( unsigned long data );
DECLARE_TASKLET( tasklet_example, tasklet_function, tasklet_data );

/∗ 调度下半部 ∗/
tasklet_schedule( &tasklet_example );

给定一个tasklet, 同一时间它只会在调度它的CPU上执行, 不同的tasklet可以同时运行在不同的cpu上.

tasklet_struct 数据结构

Tasklets API

DECLARE_TASKLET( name, func, data );
DECLARE_TASKLET_DISABLED( name, func, data);
void tasklet_init( struct tasklet_struct ∗, void (∗func)(unsigned long),
            unsigned long data );
void tasklet_disable_nosync( struct tasklet_struct ∗ );
void tasklet_disable( struct tasklet_struct ∗ );
void tasklet_enable( struct tasklet_struct ∗ );
void tasklet_hi_enable( struct tasklet_struct ∗ );

//调度函数  
void tasklet_schedule( struct tasklet_struct ∗ );
void tasklet_hi_schedule( struct tasklet_struct ∗ );

//kill函数    
void tasklet_schedule( struct tasklet_struct ∗ );
void tasklet_hi_schedule( struct tasklet_struct ∗ );

实例

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>

MODULE_LICENSE("GPL");

char my_tasklet_data[]="my_tasklet_function was called";

/∗ Bottom Half Function ∗/
void my_tasklet_function( unsigned long data )
{
   
  printk( "%s\n", (char)data );
  return;
}

DECLARE_TASKLET( my_tasklet, my_tasklet_function, 
         (
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值