Linux内核工作队列实例

schedule() , schedule_work() 以及schedule_timeout_interruptible()区别 schedule_timeout_interruptible() 用于在内核中进行可中断的睡眠,可以设置一个超时时间,允许在等待期间响应信号。总的来说,schedule() 用于实现任务调度和让出 CPU 给其他任务执行,而 schedule_work() 用于延迟执行工作函数以避免阻塞当前任务,适合在内核中异步执行一些工作。schedule() 和 schedule_work() 是 Linux 内核中用于任务调度的两个函数,它们的作用和使用场景有所不同。工作函数会在系统空闲时被调度执行。 阅读详情

29.1 前言

Linux中的工作队列是将工作推后执行的一种方式,通常用在中断分层机制中,因为中断函数的原则是(1)快;(2)不能睡眠或等待;因此,在中断驱动程序中,引入工作队列实现中断的分层,硬件处理在中断函数中处理,软件及其耗时操作则在Linux内核线程中实现。本小节,将介绍Linux内核队列及其使用方式。

29.2 工作队列特点

(1)工作队列中是可以阻塞或睡眠的;

(2)调用schedule_work(&work)后,work马上就会被调度执行;

(3)Linux工作队列属于一种异步处理机制;

(4)工作队列是通过内核进程实现的;

                                       

29.3 相关函数说明

workqueue*create_workqueue(*name)

创建工作队列;返回一个工作队列;name为工作队列名字

destroy_workqueue(struct workqueue_struct *wq)

销毁工作队列;wq为工作队列指针

queue_work(*wq,*work)

调度一个指定的工作;wq工作队列指针;work工作指针

INIT_WORK(*work,callfunc)

动态初始化工作;work为工作结构指针;callfunc为回调函数

schedule_work(*work)

工作调度;work为工作指针

schedule_delayed_work(*work,delay)

调度后延时执行;work工作指针;delay延时时间

29.4 工作队列实例

在驱动编写中,我们可以创建一个新的队列,也可以用内核已有的工作队列,这样我们就可以少去创建工作队列的代码,而直接用内核工作队列,这一般是满足我们的开发需要的。

实例1:使用内核工作队列,由内核定时器模拟中断产生调度。

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/time.h>
#include <linux/slab.h> //kmalloc头文件

#define I_DEVICE_NAME			"iTimer"
static int major;
static struct timer_list tm;

struct work_struct *work1;/*工作队列*/

void iTimer_callback(unsigned long arg)
{
	struct timeval tv;
	char *strp = (char*)arg;
	printk(KERN_EMERG "%s: %lu, %s\n", __func__, jiffies, strp);
	schedule_work(work1);

	mod_timer(&tm,jiffies+6*HZ); //每6s模拟触发一次中断调度
}

//工作队列处理函数
void work_CallBackfunc()
{
	printk(KERN_EMERG "this is second part work\n");	
}

static const struct file_operations stfops = {
	.owner	= THIS_MODULE,
};

static int __init iTest_Init(void)
{
	/* 主设备号设置为0表示由系统自动分配主设备号 */
	major = register_chrdev(0, I_DEVICE_NAME, &stfops);

	/*Linux内核定时器初始化*/
	init_timer(&tm);
	tm.function= iTimer_callback;
	tm.data = (unsigned long)"I am timer";
	tm.expires = jiffies+1*HZ;
	add_timer(&tm);

	//创建工作队列
	work1=kmalloc(sizeof(struct work_struct),GFP_KERNEL);  //第二个参数是标志
	INIT_WORK(work1,work_CallBackfunc);

	return 0;
}

static void __exit iTest_Exit(void)
{
	unregister_chrdev(major, I_DEVICE_NAME);
	del_timer(&tm);
}

module_init(iTest_Init);
module_exit(iTest_Exit);

MODULE_LICENSE("GPL");

实例2:创建新工作队列及构建工作。

static struct workqueue_struct *miki_test_wq;//声明工作队列
static struct work_struct miki_test_work;;//声明工作

/*工作处理函数*/
static void miki_test_work_callback ()
{
    //这里添加相应的逻辑,比如每隔5秒让闪关灯亮一次等
}

/*主函数*/
void mian()
{
    //创建自己的工作队列
    miki_test_wq = create_singlethread_workqueue("miki_test");
    //初始化工作,实际上是让工作work绑定工作处理函数miki_test_work_callback
    INIT_WORK(&miki_test_work, miki_test_work_callback);
    //调度执行一个指定(miki_test_wq)中的任务miki_test_work
    queue_work(miki_test_wq, &miki_test_work); 
}

 

 

 

【Linux内幕】schedule_work基本流程 1、前言 在许多情况下,设备驱动程序不需要有自己的工作队列。如果我们只是偶尔需要向队列中提交任务,则一种更简单、更有效的办法是使用内核提供的共享的默认工作队列。但是,如果我们使用了这个默认的工作队列,则应该记住我们正在和他人共享该工作队列。这意味着,我们不应该长期独占该队列,即:不能长时间休眠,而且我们的任务可能需要更长的时间才能获得处理器。 2、schedule使用步骤: 1、定义相关数据 static struct work_struct jiq_work; 2、编写要提交到工作队列中的函数 stat 阅读详情

相关推荐

Linux内核线程,定时器,工作队列编程实例

Linux内核线程,定时器,工作队列编程实例: 实例大概过程如下: 一.初始化 1.创建一个工作队列test_wq 2.创建一个定时器timer 3.创建一个内核线程 二.工作过程 1.定时器每隔500ms调用do_htimer 2.定时器触发工作队列调用do_work 3.工作队列触发睡眠的内核线程(唤醒睡眠线程) 三.结束 1.停止内核线程 2.取消定时器

855

Linux工作队列实现机制

把推后执行的任务叫做工作(work),描述它的数据结构为work_struct ,这些工作以队列结构组织成工作队列(workqueue),其数据结构为workqueue_struct ,而工作线程就是负责执行工作队列中的工作。系统默认的工作者线程为events。  工作队列(work queue)是另外一种将工作推后执行的形式。工作队列可以把工作推后,交由一个内核线程去执行—这个下半部分总是会在进程

czc0713的专栏 535

Linux内核工作队列与信号量应用实例:拆解长按Power键关机的驱动逻辑

本文深入解析了Linux内核中工作队列与信号量在高通平台PMIC驱动中的应用,详细拆解了长按Power键关机的驱动逻辑。通过设备树配置、核心数据结构设计、中断处理与状态机实现等关键环节,展示了并发编程在内核开发中的精妙应用,为开发者提供了实用的技术参考。

weixin_30588675的博客 245

内核的 工作队列 使用方法,struct work_struct

工作队列一般用来做滞后的工作,比如在中断里面要做很多事,但是比较耗时,这时就可以把耗时的工作放到工作队列。说白了就是系统延时调度的一个自定义函数。 1、定义struct work_struct irq_queue; 2、初始化INIT_WORK(&irq_queue,do_irq_queuework); 3、调用方法:schedule_work(&rq_queue); 注,

zhaoercheng1201的专栏 1362

【SABRE 3D, SABRE 3DxT,LAM设备】2025年9月12日-生产期间维护用的双重隔离

生产期间维护用的双重隔离。该程序用于准备将一个或多个双工位设置为维护状态,同时SABRE 3D/3DxT/3D Scimitar保持生产运行。其目的是在不中断生产的情况下将双工位与运行中的设备隔离。

weixin_46735260的博客 574

智能气象站:ESP32驱动的心知天气数据可视化实践

本文详细介绍了基于ESP32微控制器和心知天气API构建智能气象站的完整实践。通过Arduino开发环境,实现天气数据的获取、JSON解析与OLED屏可视化展示,涵盖硬件连接、API配置、低功耗优化及部署问题排查,为物联网开发者提供实用指南。

jump7的博客 210

workqueue

1. 什么是workqueue Linux中的Workqueue机制就是为了简化内核线程的创建。通过调用workqueue的接口就能创建内核线程。并且可以根据当前系统CPU的个数创建线程的数量,使得线程处理的事务能够并行化。workqueue是内核中实现简单而有效的机制,他显然简化了内核daemon的创建,方便了用户的编程. 工作队列(workqueue)是另外一种将工作推后执行的形式.工

997

学术规范与论文写作(雨课堂)研究生 全部答案

1:如何造就优秀的学术论文 论文语法判断题 :全部是错的 2:如何撰写学术论文 3: SCI论文写作经验分享 4:论文写作与投稿技巧 5:学术伦理道德 答案仅供参考,研究生生活不易,大家如果有时间的话,还是可以学习学习的,毕竟老师讲的不错。加油,希望读研的每一个人都能顺利毕业! ...

Always-Learning 13万+

Linux内核中断(内核中断实现过程、注册三个按键中断实例、中断底半部实例、工作队列)

工作队列用于底半部原理:内核中存在工作队列对应的内核线程,这个线程从内核启动就存在,处于休眠态。当有任务需要执行时,只需要将任务提交到工作队列中,然后唤醒休眠的内核线程,由内核线程去处理对应的任务即可。工作队列既可以用于中断,也可以用于进程。

m0_72852022的博客 691

GitHub与GitLab中的Fork操作:从个人仓库到团队协作的完整指南

本文详细介绍了GitHub与GitLab中的Fork操作,从个人仓库到团队协作的完整指南。通过Fork操作,开发者可以在权限隔离的环境下自由实验,并通过合并请求机制保证代码质量。文章涵盖了Fork的具体步骤、本地开发环境配置、代码同步方法以及高级协作技巧,帮助团队高效管理代码仓库。

weixin_28829325的博客 306

探索Vortex开源GPGPU:RISC-V SIMT架构(4-1),Execute SFU(1)

本文详细分析了Vortex RISC-V内核6级流水线中Execute阶段的SFU(特殊功能单元)模块。重点介绍了SFU的数据流结构,包含dispatch_unit、pe_switch、csr_unit、wctl_unit和gather_unit五个子模块。文章深入解析了warp控制指令wspawn和tmc的实现机制:wspawn用于激活指定数量的warp并设置新PC值,tmc则用于控制线程掩码和warp状态。通过C代码和汇编指令的对照分析,阐明了这些指令在并行计算中的关键作用,包括线程激活、状态切换和执行

weixin_55313207的博客 1363

工作队列

http://www.cnblogs.com/wwang/archive/2010/10/27/1862202.html

Gary_tian的博客 241

高项备考论文:规划绩效域

高项备考论文:规划绩效域

liuxu324的博客 1128

Linux内核机制:工作队列

一、应用场景 二、常用接口 三、应用举例

红娃子 2369

52-Halcon-- smooth_object_model_3d函数功能(滑处理3D对象模型)

Halcon中smooth_object_model_3d算子详解 该算子用于3D模型平滑处理,提供三种算法:'laplacian'(快速去噪)、'taubin'(高质量防收缩)和'low_pass'(频域滤波)。核心参数包括迭代次数(默认5)、平滑强度(0-1)和边缘保护选项。典型应用包括扫描数据去噪、CAD模型光顺和逆向工程优化。支持自适应平滑、结合模型简化等高级技巧,并可通过分块处理优化大型模型性能。参数组合需根据具体场景选择,如快速去噪推荐拉普拉斯方法(5次迭代,强度0.3),特征保持推荐低通滤波(

weixin_45590420的博客 873

MATLAB - 利用非线性模型预测控制(Nonlinear MPC)来控制四旋翼飞行器

本示例展示了如何利用非线性模型预测控制(MPC)为四旋翼飞行器设计一个跟踪轨迹的控制器。

机器人控制与仿真应用 4432

Linux内核中断底半部处理--工作队列

工作队列的使用过程: 工作队列相关函数介绍: #include /*头文件包含*/ 1.工作队列的创建及销毁: 定义一个工作队列结构体指针 static struct workqueue_struct *key_workqueue; 创建工作队列 struct workque

Eric.Xi 3404

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Linux内核实践之工作队列

工作队列(work queue)是另外一种将工作推后执行的形式,它和tasklet有所不同。工作队列可以把工作推后,交由一个内核线程去执行,也就是说,这个下半部分可以在进程上下文中执行。这样,通过工作队列执行的代码能占尽进程上下文的所有优势。最重要的就是工作队列允许被重新调度甚至是睡眠。          那么,什么情况下使用工作队列,什么情况下使用tasklet。如果推后执行的任务需

bullbat的专栏 7738

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Linux中的工作队列

工作队列(work queue)是Linux kernel中将工作推后执行的一种机制。这种机制和BH或Tasklets不同之处在于工作队列是把推后的工作交由一个内核线程去执行,因此工作队列的优势就在于它允许重新调度甚至睡眠。 工作队列是2.6内核开始引入的机制,在2.6.20之后,工作队列的数据结构发生了一些变化,因此本文分成两个部分对2.6.20之前和之后的版本分别做介绍。 1、

weed_hz的专栏 673

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Linux 驱动中工作队列的使用

工作队列 struct work_struct my_wq;//定义一个处理函数 void my_wq_func(unsigned long);//定义一个处理函数 通过INIT_WORK()可以初始化这个工作队列并将工作队列与处理函数绑定, INIT_WORK(&my_wq,(void(*)(void*)) my_wq_func, NULL); shedule_work(&my_wq)

若有博文对您有帮助,欢迎点赞关注,收藏评论。 2127

linux 内核 中断,工作队列 - Linux内核学习之中断_Linux教程_Linux公社-Linux系统门户网站...

[概述]工作队列是一种将工作推后执行的的形式,工作队列可以把工作推后,交由一个内核线程去执行,占有进程上下文的所有优势,允许重新调度和睡眠。[工作队列的实现]工作队列子系统是一个用于创建内核线程的接口,通过它创建的进程负责执行由内核其他部分排到队列里的任务。它创建的这些内核线程称作工作者线程(worker thread)。工作队列子系统提供了一个缺省的工作者线程来处理推后的工作,所以我们大多数情况...

weixin_32894769的博客 136

Linux中的工作队列(work queue)

工作队列(work queue)是Linux kernel中将工作推后执行的一种机制。这种机制和BH(bottom half)或Tasklets不同之处在于工作队列是把推后的工作交由一个内核线程去执行,因此工作队列的优势就在于它允许重新调度甚至睡眠。 linux 2.6.20以后,工作队列机制和之前的版本有一点不同,在网上找了一点资料,也相应的看了一些code,现在自己总结一下:原文参

Haibin Yu 3193

linux内核工作队列使用总结

  我总结出的内核工作队列中的4种用法 1. 使用系统的工作队列(不延迟)   1)定义一个工作: struct work_struct my_work;   2)编写一个函数: void my_work_func (struct work_struct *p_work) { printk("work func\n"); }   3)将工作和函数...

weixin_30764771的博客 94

linux 工作队列 传参,Linux内核工作队列如何传参数

释放创建的工作队列。下面一段代码可以看作一个简单的实作: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”);struc...

weixin_42443992的博客 707

Linux内核学习之中断(2)-工作队列

工作队列 [概述] 工作队列是一种将工作推后执行的的形式,工作队列可以把工作推后,交由一个内核线程去执行,占有进程上下文的所有优势,允许重新调度和睡眠。   [工作队列的实现] 工作队列子系统是一个用于创建内核线程的接口,通过它创建的进程负责执行由内核其他部分排到队列里的任务。它创建的这些内核线程称作工作者线程(worker thread)。工作队列子系统提供了一个缺省的工作者线程来处理

liaoye's blog 2067
上一篇: Linux内核定时器简介及使用
下一篇: libevent HTTPserver/ libcurl HTTPClient构建
Chasing_Chasing
博客等级 码龄10年 233粉丝 87原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值