如何使用queue_delayed_work函数

queue_delayed_work函数是Linux kernel中的一种异步工作调度方法,通常用于实现一些需要周期性执行的任务,如定时器、定时刷新等等。

函数定义:

int queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *work, unsigned long delay);

参数说明:

- wq:指向工作队列的指针,表示将工作先放到该队列中,待到合适的时机再取出执行;

- work:指向工作结构体的指针,表示即将要放入队列的工作;

- delay:表示延时执行的时间。单位为jiffies(1/1000秒),可以使用常量HZ来表示。

函数返回值:

- 如果函数成功调度了工作,则返回1;

- 如果工作的延迟时间为0,或者队列已经满了,或者工作没有初始化,则返回0;

- 如果出现了错误(如工作队列指针为空),则返回负值。

queue_delayed_work的作用是将一个delayed_work类型的结构体添加进内核的工作队列,延迟一定的时间后执行这个工作。这个工作可以理解为一个函数或者一个执行单元,可以是内核或者模块中的函数,也可以是某个内核或者模块中的操作或者逻辑。

使用queue_delayed_work的基本步骤如下:

1. 定义delayed_work类型的结构体和执行函数

```c

#include

#include

struct my_work_struct {

struct delayed_work work;

int param1;

char *param2;

};

void my_work_function(struct work_struct *work) {

struct my_work_struct *my_work = container_of(work,

struct my_work_struct, work.work);

// do some work...

msleep(100);

printk(KERN_ALERT "my_work_function executed, param1 = %d, param2 = %s\n",

my_work->param1, my_work->param2);

return;

}

```

上述代码中,my_work_struct是一个定时工作的结构体。它包含了一个delayed_work成员,并且还定义了两个成员变量:param1和param2。my_work_function函数是实现定时工作的执行函数,函数内部包含了需要执行的具体操作,最后打印一条信息以示执行完毕。

2. 创建&初始化该结构体

```c

struct my_work_struct *my_work;

my_work = kmalloc(sizeof(struct my_work_struct), GFP_KERNEL);

if (!my_work) {

printk(KERN_ALERT "Failed to allocate my_work.\n");

return;

}

INIT_DELAYED_WORK(&my_work->work, my_work_function);

my_work->param1 = 1234;

my_work->param2 = "hello, kernel!";

```

在这一步中,我们创建并初始化my_work_struct结构体,包括delayed_work结构体和成员变量。

3. 将该结构体加入工作队列

```c

int ret = queue_delayed_work(my_queue, &my_work->work, HZ * 10);

if (!ret) {

printk(KERN_ALERT "Failed to queue delayed work\n");

}

```

在这一步中,我们调用queue_delayed_work()函数将my_work结构体添加进my_queue队列。这个工作将在10秒后执行。

示例代码:

```c

#include

#include

//定义定时工作的结构体

struct my_work_struct {

struct delayed_work work;

int param1;

char *param2;

};

//定义定时工作的执行函数

void my_work_function(struct work_struct *work) {

struct my_work_struct *my_work = container_of(work,

struct my_work_struct, work.work);

// do some work...

msleep(100);

printk(KERN_ALERT "my_work_function executed, param1 = %d, param2 = %s\n",

my_work->param1, my_work->param2);

return;

}

//定义工作队列的指针

static struct workqueue_struct *my_queue;

static int __init demo_init(void) {

struct my_work_struct *my_work;

//初始化工作队列

my_queue = create_singlethread_workqueue("my_queue");

if (!my_queue) {

printk(KERN_ALERT "Failed to create my_queue.\n");

return -ENOMEM;

}

//定义定时工作的结构体

my_work = kmalloc(sizeof(struct my_work_struct), GFP_KERNEL);

if (!my_work) {

printk(KERN_ALERT "Failed to allocate my_work.\n");

return -ENOMEM;

}

//初始化定时工作结构体

INIT_DELAYED_WORK(&my_work->work, my_work_function);

my_work->param1 = 1234;

my_work->param2 = "hello, kernel!";

//添加定时工作到工作队列

int ret = queue_delayed_work(my_queue, &my_work->work, HZ * 10);

if (!ret) {

printk(KERN_ALERT "Failed to queue delayed work\n");

}

return 0;

}

static void __exit demo_exit(void) {

//销毁工作队列

if (my_queue) {

flush_workqueue(my_queue);

destroy_workqueue(my_queue);

}

}

module_init(demo_init);

module_exit(demo_exit);

MODULE_LICENSE("GPL");

```

示例代码中,我们首先声明了一个my_work_struct结构体,其中包含一个delayed_work类型的对象和两个成员变量:param1和param2。紧接着定义了一个实现具体逻辑的my_work_function函数,该函数完成一些工作后,打印一条信息以表示该定时任务已经被执行完毕。

然后,我们在模块初始化函数demo_init中,先创建了一个名字为“my_queue”的工作队列my_queue,然后为my_work_struct类型的my_work对象分配内存并初始化,最后调用queue_delayed_work函数将my_work对象放入my_queue里面,设定了定时时间为10秒。

在模块退出函数demo_exit中,我们先使用flush_workqueue函数将队列里面的工作全部执行完,则销毁my_queue队列。

壹涵网络我们是一家专注于网站建设、企业营销、网站关键词排名、AI内容生成、新媒体营销和短视频营销等业务的公司。我们拥有一支优秀的团队,专门致力于为客户提供优质的服务。

我们致力于为客户提供一站式的互联网营销服务,帮助客户在激烈的市场竞争中获得更大的优势和发展机会!

点赞(113) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部