linux内核 队列末尾,Linux内核工作队列

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:工作队列名称。传入值为字符串,和共享工作队列里的参数不同。

返回值:工作队列指针

二、常用接口说明

工作任务定义

工作任务添加

工作任务清除

工作任务取消

DECLARE_WORK()

schedule_work()

flush_work()

cancel_work_sync()

DECLARE_DELAYED_WORK()

schedule_delayed_work()

flush_delayed_work()

cancel_delayed_work()cancel_delayed_work_sync()

INIT_WORK()

schedule_work()

flush_work()

cancel_work_sync()

INIT_DELAYED_WORK()

schedule_delayed_work()

flush_delayed_work()

cancel_delayed_work()cancel_delayed_work_sync()

create_workqueue()

queue_work()queue_delayed_work()queue_work_on()

flush_workqueue()

destroy_workqueue()

create_singlethread_workqueue()

queue_work()

flush_workqueue()

destroy_workqueue()

注:

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(&gtp_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, &gtp_esd_check_work, ts->clk_tick_cnt);

...

## 5.等待延时任务完成

cancel_delayed_work_sync(&gtp_esd_check_work);

...

}

static int goodix_ts_remove(struct i2c_client *client)

{

...

## 6.销毁工作队列gtp_esd_check_workqueue

destroy_workqueue(gtp_esd_check_workqueue);

...

}

注:工作队列允许任务重新调度和睡眠。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值