在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和延时工作队列相关推荐

  1. SylixOS 延时工作队列实现原理详解

    SylixOS系统工作队列内部其实分两部分,简单工作队列(simple work queue)和 延时工作队列(delay work queue). 简单工作队列由__wqS打头的函数簇实现,本质是基 ...

  2. 六、系统软中断、tasklet、工作队列work queue的区别及使用

    前言:这篇文章不会对系统软中断.tasklet.工作队列work queue的内核实现机制进行深入分析,仅仅是谈一下这几种机制的不同以及简单的使用.有描述不对的地方,欢迎大家指出. 说明:在分析具体代 ...

  3. linux 用户空间 和 内核空间 延时函数

    用户空间: 1.unsigned int sleep(unsigned int seconds);   sleep()会使当前程序休眠seconds秒.如果sleep()没睡饱,它将会返回还需要补眠的 ...

  4. Linux环境编程多线程定时器、延时队列以及分布式定时器的现实与原理分析

    Linux环境编程多线程定时器.延时队列以及分布式定时器的现实与原理分析丨线程池丨中间件丨后端开发丨C/C++linux服务器开发 视频讲解如下,点击观看: Linux环境编程多线程定时器.延时队列以 ...

  5. Linux系统中的定时任务及延时任务详解

    Linux系统中的定时任务及延时任务 1.系统延时任务 at 23:37/now+1min ##设定任务执行时间/延时1分钟 at> rm -fr /mnt/* ##任务动作 at> &l ...

  6. Rabbitmq学习笔记三:工作队列work queue

    前面我们已经实现了[rabbitMQ的helloWorld]参见(http://blog.csdn.net/u010416588/article/details/54615920), 这篇中我们将会创 ...

  7. Linux基础篇-10-带宽、延时、吞吐率、PPS

    1.简介 Linux 网络协议栈是根据 TCP/IP 模型来实现的,TCP/IP 模型由应用层.传输层.网络层和网络接口层,共四层组成,每一层都有各自的职责. 2.用什么指标来衡量 Linux 的网络 ...

  8. linux c不占用cpu的延时,linux下写个C语言程序,要求有0.5微秒以下的延时,要怎样写...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 #include #include #include #include #define B break void de(int timee) { unsi ...

  9. Linux 系统中的定时任务及延时任务

    ######系统延时任务及定时任务###### ##1.系统延时任务## [root@localhost1 ~]# at 23:37        ##设定任务执行时间 at> rm -fr / ...

  10. Linux 下wifi 驱动开发(三)—— SDIO接口WiFi驱动浅析

    SDIO-Wifi模块是基于SDIO接口的符合wifi无线网络标准的嵌入式模块,内置无线网络协议IEEE802.11协议栈以及TCP/IP协议栈,能够实现用户主平台数据通过SDIO口到无线网络之间的转 ...

最新文章

  1. matlab读取h5文件
  2. zentao这php,ZenTaoPHP后面计划
  3. UA MATH571B 试验设计V 2K析因设计简介
  4. 安装Python3后再安装Python2
  5. mysql三大范式 答案_数据库三大范式的个人理解~!
  6. 430单片机实现三人投票表决器_长虹KFR-28变频空调器室内机控制板电路原理分析...
  7. django和mysql如何建模_Django中的多个数据库和多个模型
  8. Linux shell命令提示符
  9. iOS开发之tintColor属性详解
  10. Windows 7 SP1开发完毕 已进入测试阶段
  11. printf格式控制符的完整格式
  12. Java | Comparable接口和Comparator接口比较
  13. 一键下载网页所有图片,把美丽存下来
  14. 果园树枝分割论文汇总
  15. 红葡萄酒质量影响因素分析
  16. idea如何配置或者创建mybatis的xml文件 idea如何配置或者创建mybatis的配置文件
  17. 简单音乐播放器html+css+基础vue+含源码,有搜索和播放mv功能,代码可直接复制用。
  18. linux定时 top、netstat 输出到文件
  19. Deep Knowledge Tracing with Transformers论文阅读
  20. 手把手教你搭建K3S产线集群

热门文章

  1. HTML和CSS代码片段快速编写方式(Emmet Documentation)
  2. 无法import的原因(ImportError: No module named *****)
  3. [分享]Java 线程池的原理与实现
  4. NLP标注神器:可同时对文本类型与实体类型进行标注(动图演示)
  5. 如何判断你和优秀AI算法工程师之间的差异?
  6. 通俗易懂!《图机器学习导论》附69页PPT
  7. 深度学习之激活函数详解
  8. 是时候研读一波导师的论文--一个简单有效的联合模型
  9. 来字节一月了,四个字:翻天覆地
  10. 深度学习2.0-2.tensorflow的基础操作之创建Tensor及应用场景