Linux的工作队列work queue和延时工作队列
在linux中,当你想延时几秒或者几毫秒再执行一个任务或者自定义的一个函数时,延时工作队列是你最好的选择。在你的任务或者函数中,加上queue_delayed_work,就可以每隔一段时间执行一次你的任务或者自定义的一个函数,具体实现如下:
按如下步骤:
首先还是要添加上工作队列的相关头文件,头文件一般有这些函数的声明和定义,include了相关的头文件,我们才能随心所欲的使用这些头文件里面的函数,达到我们的目的:
#include <linux/workqueue.h>
一.声明一个工作队列
static struct workqueue_struct *test_wq;
二.声明一个延期工作描述实例
static struct delayed_work test_delay_wq;
三.声明并实现一个工作队列延迟处理函数
void test_power_delay_work_func(struct work_struct *work){int value;value = get_adc_sample(0, CHAN_1); //这里调用adc接口去读取数据pr_err("-czd-: current power adc value is %d\n", value);queue_delayed_work(test_wq, &test_delay_wq, msecs_to_jiffies(5000)); //加上这句就可以每隔5秒钟执行一次这个函数test_power_delay_work_func,不加就只执行一次,时间msecs_to_jiffies(5000)可以设置别的时间,这里是5秒,相关部分想了解更多可以百度}
四.初始化一个工作队列(在init模块加载函数添加或者在probe函数添加)
test_wq = create_workqueue("test_wq");
if (!test_wq) { printk(“-czd-: No memory for workqueue\n"); return 1; }
五. 任务初始化(在init模块加载函数添加或者在probe函数添加)
INIT_DELAYED_WORK(&test_delay_wq, test_power_delay_work_func);
六.向工作队列提交工作项(在init模块加载函数添加或者在probe函数添加)
ret = queue_delayed_work(test_wq, &test_delay_wq, msecs_to_jiffies(5000));
pr_err("-czd-: ret=%d\n", ret);
七.取消工作队列中的工作项
int cancel_delayed_work(test_wq);
如果这个工作项在它开始执行前被取消,返回值是非零。内核保证给定工作项的执行不会在调用 cancel_delay_work 成功后被执行。 如果 cancel_delay_work 返回 0,则这个工作项可能已经运行在一个不同的处理器,并且仍然可能在调用 cancel_delayed_work 之后被执行。要绝对确保工作函数没有在 cancel_delayed_work 返回 0 后在任何地方运行,你必须跟随这个调用之后接着调用 flush_workqueue。在 flush_workqueue 返回后。任何在改调用之前提交的工作函数都不会在系统任何地方运行。
八.刷新工作队列
flush_workqueue(test_wq);
九.工作队列销毁
destroy_workqueue(test_wq);
七八九可以同时添加到exit函数中,例如以下:
static void __exit module_exit(void)
{ int ret; ret = cancel_delayed_work(&test_dwq); flush_workqueue(test_wq);destroy_workqueue(test_wq);printk("-czd-: enter %s, ret=%d\n", __func__, ret);
}
除了上面调用的queue_delayed_work之外,使用schedule_delayed_work也是可以的。其实schedule_delayed_work最终返回调用的还是queue_delayed_work。函数声明在include/linux/workqueue.h中。
static inline bool schedule_delayed_work(struct delayed_work *dwork,unsigned long delay){return queue_delayed_work(system_wq, dwork, delay);}
下面的demo是实现3秒之后再执行work_queue:
#include <linux/workqueue.h>static struct delayed_work send_event; //定义一个delay_workstatic void send_event_workq(struct work_struct *work) //定义你要延时执行的函数{rk_send_wakeup_key();printk("***************charger mode send wakeup key\n\n");schedule_delayed_work(&send_event, msecs_to_jiffies(3000)); //添加之后每隔3秒执行一次}static int __init module_init(void){INIT_DELAYED_WORK(&send_event, send_event_workq); //初始化工作队列schedule_delayed_work(&send_event, msecs_to_jiffies(3000)); //添加到延时工作队列,这里延时3秒}static void __exit module_exit(void) { cancel_delayed_work_sync(&send_event); //取消延时工作队列}
下面是创建一个工作队列的demo 代码:
#include <linux/workqueue.h>void my_func(void *data){char *name = (char *)data;printk(KERN_INFO “Hello world, my name is %s!\n”, name);}struct workqueue_struct *my_wq = create_workqueue(“my wq”);struct work_struct my_work;INIT_WORK(&my_work, my_func);queue_work(my_wq, &my_work);destroy_workqueue(my_wq);
Linux的工作队列work queue和延时工作队列相关推荐
- SylixOS 延时工作队列实现原理详解
SylixOS系统工作队列内部其实分两部分,简单工作队列(simple work queue)和 延时工作队列(delay work queue). 简单工作队列由__wqS打头的函数簇实现,本质是基 ...
- 六、系统软中断、tasklet、工作队列work queue的区别及使用
前言:这篇文章不会对系统软中断.tasklet.工作队列work queue的内核实现机制进行深入分析,仅仅是谈一下这几种机制的不同以及简单的使用.有描述不对的地方,欢迎大家指出. 说明:在分析具体代 ...
- linux 用户空间 和 内核空间 延时函数
用户空间: 1.unsigned int sleep(unsigned int seconds); sleep()会使当前程序休眠seconds秒.如果sleep()没睡饱,它将会返回还需要补眠的 ...
- Linux环境编程多线程定时器、延时队列以及分布式定时器的现实与原理分析
Linux环境编程多线程定时器.延时队列以及分布式定时器的现实与原理分析丨线程池丨中间件丨后端开发丨C/C++linux服务器开发 视频讲解如下,点击观看: Linux环境编程多线程定时器.延时队列以 ...
- Linux系统中的定时任务及延时任务详解
Linux系统中的定时任务及延时任务 1.系统延时任务 at 23:37/now+1min ##设定任务执行时间/延时1分钟 at> rm -fr /mnt/* ##任务动作 at> &l ...
- Rabbitmq学习笔记三:工作队列work queue
前面我们已经实现了[rabbitMQ的helloWorld]参见(http://blog.csdn.net/u010416588/article/details/54615920), 这篇中我们将会创 ...
- Linux基础篇-10-带宽、延时、吞吐率、PPS
1.简介 Linux 网络协议栈是根据 TCP/IP 模型来实现的,TCP/IP 模型由应用层.传输层.网络层和网络接口层,共四层组成,每一层都有各自的职责. 2.用什么指标来衡量 Linux 的网络 ...
- linux c不占用cpu的延时,linux下写个C语言程序,要求有0.5微秒以下的延时,要怎样写...
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include #include #define B break void de(int timee) { unsi ...
- Linux 系统中的定时任务及延时任务
######系统延时任务及定时任务###### ##1.系统延时任务## [root@localhost1 ~]# at 23:37 ##设定任务执行时间 at> rm -fr / ...
- Linux 下wifi 驱动开发(三)—— SDIO接口WiFi驱动浅析
SDIO-Wifi模块是基于SDIO接口的符合wifi无线网络标准的嵌入式模块,内置无线网络协议IEEE802.11协议栈以及TCP/IP协议栈,能够实现用户主平台数据通过SDIO口到无线网络之间的转 ...
最新文章
- 牛客多校6 - Harmony Pairs(数位dp)
- 2017年秋招-广联达面试及思考
- 【opencv】visualstudio实现opencvblobslib编译
- Service服务学习(SimpleRandomServiceDemo)
- DPDK初始化分析(四)
- 国内刊物(杂志社,编辑部)联系方式列表 zt
- 机械制图类毕业论文文献有哪些?
- html可以转换wps嘛,如何将图文并茂的网页快速转换为WPS或word文档
- Ubuntu下查看隐藏文件
- 程序员:世界如此精彩何故钟情code
- POI 在 word中 画图 以及图例刷新
- SX1308原厂芯片
- 根据GFF3文件统计外显子大小和数量以及内含子大小
- 对数据驱动运营的理解
- windows搭建php运行环境,Windows手动搭建PHP运行环境
- Go开发 之 基础语法(常量、枚举、注释、类型别名、指针)
- (centos7-x86)编译安装zabbix6.0LTS+Mariadb10.5+Apache+php7.4【安装完整版】
- C语言实现文件的局部修改,C语言:在文件的指定位置实现局部修改,而无需重写文件的其他部分...
- moon服务器 zerotier_初探:建立 zerotier 的 moon 服务器
- 太方便了,告别复制粘贴,Python 轻松实现 PDF 转文本
热门文章
- js实现的笛卡尔乘积-商品发布
- 调用 WebService 请求因 HTTP 状态 407 失败
- nginx低版本不支持pathinfo模式,thinkphp针对此问题的解决办法
- 选择爱人的数学方法(经典秘书问题)
- javascript ajax调用asp.net后台方法
- 《Windows via C/C++》学习笔记 —— 用户模式的“线程同步”之“条件变量”
- 071120 sunny
- 【ICLR2021必读】 【自监督学习】 【Transformer】相关论文
- 2019.2.4时GitHub超过15个粉丝就可以领取3000元啦!
- 百面机器学习—模型复杂度与模型的方差、偏差的关系