发布于2026-08-20 阅读(0)
扫一扫,手机访问
Linux内核中实现工作推后执行的方法有:软中断、tasklet和工作队列(work queue)。

本文介绍工作队列的简单用法。
Linux内核中的工作队列包括:共享工作队列和自定义工作队列。区别如下:
1)共享工作队列:将新创建的工作任务添加到Linux内核创建的全局工作队列system_wq中;
2)自定义工作队列:将新创建的工作任务添加到自己创建的工作队列中;
1、共享工作队列
1)、静态定义
宏:DECLARE_WORK(n, f),文件:include/linux/workqueue.h,定义如下:
#define DECLARE_WORK(n, f)
struct work_struct n = __WORK_INITIALIZER(n, f)参数:
n:表示工作任务的名称;
f:表示工作任务的实现函数;
类似接口:DECLARE_DELAYED_WORK(n, f),创建延时工作任务。
2)、动态定义
文件:include/linux/workqueue.h,定义如下:
#define INIT_WORK(_work, _func)
__INIT_WORK((_work), (_func), 0)参数:
_work:表示工作任务的名称;
_func:表示工作任务的实现函数;
2、自定义工作队列
文件:include/linux/workqueue.h,定义如下:
#define create_workqueue(name)
alloc_workqueue("%s", WQ_MEM_RECLAIM, 1, (name))
#define create_singlethread_workqueue(name)
alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM, name)参数:
name:工作队列名称。传入值为字符串,和共享工作队列里的参数不同。
返回值:工作队列指针
注:
1、flush_work():堵塞工作任务,直到工作任务完成
2、flush_delayed_work():等待延时工作任务完成
3、cancel_work_sync():取消工作任务并等待它完成
4、cancel_delayed_work():取消延时工作任务
5、cancel_delayed_work_sync():取消延时工作任务并等待它完成
6、create_workqueue():在多CPU系统里,内核会给每个CPU都创建一个工作队列,这样就能让线程处理实现并行化。
7、create_singlethread_workqueue():内核只在一个CPU上创建一个工作队列
8、queue_work_on():此函数用于在指定的CPU上添加工作任务。而queue_work()实际上是调用了queue_work_on(),从而实现在所有CPU上添加工作任务。
1、共享工作队列
文件:drivers/gpu/drm/drm_fb_helper.c,举例如下:
## 3、工作任务的具体实现
static void drm_fb_helper_restore_work_fn(struct work_struct *ignored)
{
...
}
## 1、定义工作任务,名称:drm_fb_helper_restore_work,实现函数:drm_fb_helper_restore_work_fn
static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn);
static void drm_fb_helper_sysrq(int dummy1)
{
## 2、将drm_fb_helper_restore_work加入到全局工作队列
schedule_work(&drm_fb_helper_restore_work);
}其它接口使用方法类似。
2、自定义工作队列
文件:drivers/input/touchscreen/gt9xx/gt9xx.c
## 1.定义工作任务和工作队列
static struct delayed_work gtp_esd_check_work;
static struct workqueue_struct * gtp_esd_check_workqueue = NULL;
static int goodix_ts_init(void)
{
...
## 2.初始化工作任务gtp_esd_check_work; 创建工作队列gtp_esd_check_workqueue
INIT_DELAYED_WORK(>p_esd_check_work, gtp_esd_check_func);
gtp_esd_check_workqueue = create_workqueue("gtp_esd_check");
...
}
## 3.工作任务gtp_esd_check_work的实现函数
static void gtp_esd_check_func(struct work_struct *work)
{
...
}
void gtp_esd_switch(struct i2c_client *client, s32 on)
{
...
## 4.将工作任务gtp_esd_check_work添加到工作队列gtp_esd_check_workqueue,延时调度
queue_delayed_work(gtp_esd_check_workqueue, >p_esd_check_work, ts->clk_tick_cnt);
...
## 5.等待延时任务完成
cancel_delayed_work_sync(>p_esd_check_work);
...
}
static int goodix_ts_remove(struct i2c_client *client)
{
...
## 6.销毁工作队列gtp_esd_check_workqueue
destroy_workqueue(gtp_esd_check_workqueue);
...
}注:工作队列允许任务重新调度和睡眠。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
4
5
6
7
8
9