当前位置: 首页 > news >正文

共和网站建设公司wordpress本地环境迁移步骤

共和网站建设公司,wordpress本地环境迁移步骤,惠州专业网站制作公司,东莞建网站多年前就了解了workqueue着玩意#xff0c;但理解上就并不是很很深刻#xff0c;今天重新梳理一下#xff0c;本文重点的是哪个些现成的demo代码#xff0c;都是可以直接拿来用的#xff0c;这就是写这文章的目的和作用#xff0c;就是为了备份后续工作用到的时候#x…        多年前就了解了workqueue着玩意但理解上就并不是很很深刻今天重新梳理一下本文重点的是哪个些现成的demo代码都是可以直接拿来用的这就是写这文章的目的和作用就是为了备份后续工作用到的时候可以快速Ctrlc and Ctrl v接下来复制些前辈写好的理解概念再结合一下个所整理得demo。 一、workqueue工作队列简介 工作队列是除软中断和tasklet以外最常用的一种下半部机制其基本原理是把work需要推迟执行的函数交由一个内核线程来执行工作队列总是在进程上下文执行。                               工作队列 ( workqueue )是将操作或回调延期异步执行的一种机制。工作队列可以把工作推后交由一个内核线程去执行并且工作队列是执行在线程上下文中因此工作执行过程中可以被重新调度、抢占、睡眠。 ​ 工作队列的优点 因工作队列在进程下文中执行因此工作队列允许重新调度和睡眠是异步执行的进程上下文。     解决了如果软中断和tasklet执行时间过长会导致系统实时性下降等问题。 1-1work_struct工作 在 Linux 内核中work_struct 是工作队列workqueue机制的核心数据结构用于表示一个工作项。工作队列允许内核将任务推迟到其他线程中执行这在处理中断或其他需要快速响应的场景中非常有用 struct my_work {struct work_struct work;int data; };定义一个包含 work_struct 的结构体用于存储工作项的数据 linux内核中使用work_struct结构体来表示一个工作如下定义/inlcude/linux/workqueue.h struct work_struct {atomic_long_t data;struct list_head entry;work_func_t func; #ifdef CONFIG_LOCKDEPstruct lockdep_map lockdep_map; #endif }; 1-2workqueue工作队列 把工作包括该工作任务的执行回调函数添加到一个队列称为workqueue即工作队列然后通过worker-pool中的内核工作线程worker去执行这个回调函数。工作队列使用workqueue_struct结构体来表示定义如下/kernel/workqueue.c 创建工作队列my_workqueue create_workqueue(my_workqueue);使用 create_workqueue 创建一个工作队列名称为 my_workqueue 1-3worker工作者线程 ​ linux 内核使用工作者线程(worker thread)来处理工作队列中的各个工作linux 内核使用 worker 结构体表示工作者线程worker 结构体定义如下/kernel/workqueue_internal.h    二、workqueue工作队列的使用 ​ 每一个worker工作线程中都有一个工作队列工作线程处理自己工作队列中的所有工作。 在实际开发中推荐使用默认的workqueue·工作队列而不是新创建workqueue。使用方法如下 ​ 直接定义一个work_struct结构体变量然后使用INIT_WORK宏来完成初始化工作INIT_WORK定义如下 #define INIT_WORK(_work, _func) _work表示要初始化的工作_func是工作对应的处理函数。 也可以使用 DECLARE_WORK 宏一次性完成工作的创建和初始化宏定义如下 #define DECLARE_WORK(n, f) ​ n 表示定义的工作(work_struct)f 表示工作对应的处理函数。和 tasklet 一样工作也是需要调度才能运行的工作的调度函数为schedule_work()函数原型如下所示 bool schedule_work(struct work_struct *work) //其实你就理解为工作队列启动回调的函数 使用cancel_work_sync()取消一个工作函数原型如下所示 bool cancel_work_sync(struct work_struct *work) 当然也可以自己创建一个workqueue特别是网络子系统、块设备子系统情况下等。具体步骤如下 使用alloc_workqueue()创建新的workqueue。     使用INIT_WORK()宏声明一个work和该work的回调函数。     使用queue_work()在新的workqueue上调度一个work //其实就理解为工作队列启动回调的函数     使用flush_workqueue()去flush 工作队列上的所有work。 来个demo #include linux/init.h #include linux/module.h #include linux/time.h#include linux/jiffies.h #include linux/workqueue.h #include linux/slab.h //kmalloc kfree#include linux/sched.h #include linux/delay.h#define WAIT_TIMES 5000static char data[] [Tab] test for demo work;struct work_ctx{struct work_struct real_work;char *str;int arg; }work_ctx;struct work_ctx *demo_work;// 定义工作队列 static struct workqueue_struct *my_workqueue;static void demo_work_func(struct work_struct *work){struct work_ctx *temp_work container_of(work,struct work_ctx,real_work);printk(KERN_INFO [work] PID: %d; NAME: %s\n, current-pid, current-comm);printk(KERN_INFO [work] sleep 1 seconds\n);set_current_state(TASK_INTERRUPTIBLE);schedule_timeout(1 * HZ); //Wait 1 secondsprintk(KERN_INFO [work] data is: %d %s\n, temp_work-arg,temp_work-str); }static int __init demo_thread_init(void){int count 10;// 创建工作队列my_workqueue create_workqueue(my_workqueue);if (!my_workqueue) {return -ENOMEM;} demo_work kmalloc(sizeof(*demo_work),GFP_KERNEL); INIT_WORK(demo_work-real_work, demo_work_func);demo_work-str data;while(count--){//msleep(5000);msleep(WAIT_TIMES);//mdelay(WAIT_TIMES);demo_work-arg count;//schedule_work(demo_work-real_work);// 提交工作项到工作队列//queue_work(my_workqueue, my_work-work); queue_work(my_workqueue, demo_work-real_work);}return 0; }module_init(demo_thread_init);static void __exit demo_thread_exit(void){flush_work(demo_work-real_work);kfree(demo_work); } module_exit(demo_thread_exit);MODULE_LICENSE(GPL); 除此之外linux内核还提供了一个workqueue机制与timer机制相结合的延时机制—delayed_work。 Talk is cheapshow me the code 结合hrtimer_demo升级了一下 #include linux/module.h #include linux/kernel.h #include linux/init.h #include linux/hrtimer.h #include linux/ktime.h#include linux/time.h#include linux/jiffies.h #include linux/workqueue.h #include linux/slab.h //kmalloc kfree#include linux/sched.h #include linux/delay.hstatic struct hrtimer my_timer; static int count 0;#define WAIT_TIMES 5000static char data[] [Tab] test for demo work;struct work_ctx{struct work_struct real_work;char *str;int arg; }work_ctx;struct work_ctx *demo_work;// 定义工作队列 static struct workqueue_struct *my_workqueue;static void demo_work_func(struct work_struct *work){struct work_ctx *temp_work container_of(work,struct work_ctx,real_work);printk(KERN_INFO [work] PID: %d; NAME: %s\n, current-pid, current-comm);printk(KERN_INFO [work] sleep 1 seconds\n);set_current_state(TASK_INTERRUPTIBLE);schedule_timeout(1 * HZ); //Wait 1 secondsprintk(KERN_INFO [work] data is: %d %s\n, temp_work-arg,temp_work-str); }#if 1 enum hrtimer_restart my_timer_callback(struct hrtimer *timer) {count;//pr_info(Timer expired! Count: %d\n, count);printk(enter [%s] line %d, count %d. \n, __func__, __LINE__, count);demo_work-arg count;schedule_work(demo_work-real_work);// 提交工作项到工作队列 //queue_work(my_workqueue, demo_work-real_work); // 重新启动定时器设置下次到期时间为 1 秒hrtimer_forward_now(timer, ms_to_ktime(2000));//调整高分辨率定时器high-resolution timerhrtimer到期时间的一个函数return HRTIMER_RESTART; // 代表重复定时器 //重启方式 } #elseenum hrtimer_restart my_timer_callback(struct hrtimer *timer) {count;//pr_info(Timer expired! Count: %d\n, count);printk(enter [%s] line %d, count %d. \n, __func__, __LINE__, count);// 重新启动定时器设置下次到期时间为 1 秒hrtimer_forward_now(timer, ms_to_ktime(2000));//调整高分辨率定时器high-resolution timerhrtimer到期时间的一个函数return HRTIMER_RESTART; // 代表重复定时器 //重启方式 }enum hrtimer_restart my_timer_callback(struct hrtimer *timer) {pr_info(KERN_INFO High-resolution timer expired after 1 second\n);printk(enter [%s] line %d, count %d. \n, __func__, __LINE__, count);return HRTIMER_NORESTART; // 代表不重复定时器 } #endifstatic int __init my_module_init(void) {ktime_t ktime;printk(enter [%s] line %d \n, __func__, __LINE__);pr_info(High-Resolution Timer Example Module Loaded\n);// 创建工作队列my_workqueue create_workqueue(my_workqueue);if (!my_workqueue) {return -ENOMEM;} demo_work kmalloc(sizeof(*demo_work),GFP_KERNEL); INIT_WORK(demo_work-real_work, demo_work_func);demo_work-str data;// 设置定时器初始时间为 1 秒ktime ktime_set(10, 0); // 1 秒, 0 纳秒hrtimer_init(my_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);//初始化高分辨率定时器的函数my_timer.function my_timer_callback;// 定时到期时的回调函数hrtimer_start(my_timer, ktime, HRTIMER_MODE_REL);//启动高分辨率定时器的函数return 0; }static void __exit my_module_exit(void) {// 停止定时器hrtimer_cancel(my_timer);pr_info(High-Resolution Timer Example Module Unloaded\n); }module_init(my_module_init); module_exit(my_module_exit);MODULE_LICENSE(GPL); MODULE_DESCRIPTION(High-Resolution Timer Example); MODULE_AUTHOR(Pan Shuai); 原文链接https://blog.csdn.net/iriczhao/article/details/122870227 Linux内核中的工作队列包括共享工作队列和自定义工作队列。区别如下 1共享工作队列将新创建的工作任务添加到Linux内核创建的全局工作队列system_wq中无需自己创建工作队列 2自定义工作队列将新创建的工作任务添加到自己创建的工作队列中 #include linux/kernel.h #include linux/module.h #include linux/slab.h #include linux/kobject.h #include linux/list.h #include linux/kthread.h #include asm/ptrace.h #include linux/sched.h #include linux/delay.h #include linux/interrupt.hint data 10;static struct work_struct work1; static struct work_struct work2;static void do_work1(struct work_struct *arg) {printk(KERN_INFO do_work1 .....); }static void do_work2(struct work_struct *arg) {printk(KERN_INFO do_work2 .....); }int threadfn(void *data) {static int count 0 ;int args *(int *)data;printk(KERN_INFO enter thead_fn);while(1){msleep(2*1000);printk(KERN_INFO threadfn data: %d, count: %d,args , count);schedule_work(work1);schedule_work(work2);} } static int __init test_kobj_init(void) {INIT_WORK(work1,do_work1);INIT_WORK(work2,do_work2);struct task_struct * thread kthread_create( threadfn,(void * )data,mythread);if(thread ! NULL){printk(KERN_INFO thread create success);wake_up_process(thread);}else{printk(KERN_ERR thread create err);}return 0; }static void __exit test_kobj_exit(void) {printk(KERN_INFO test_kobj_exit );return; }module_init(test_kobj_init); module_exit(test_kobj_exit);MODULE_AUTHOR(copy other auther); MODULE_LICENSE(GPL);2、自定义工作队列举例demol来源于网络 #include linux/kernel.h #include linux/module.h #include linux/slab.h #include linux/kobject.h #include linux/list.h #include linux/kthread.h #include asm/ptrace.h #include linux/sched.h #include linux/delay.h #include linux/interrupt.h int data 10;static struct workqueue_struct *workqueue; static struct work_struct work1; static struct work_struct work2;static void do_work1(struct work_struct *arg) {printk(KERN_INFO do_work1 .....); }static void do_work2(struct work_struct *arg) {printk(KERN_INFO do_work2 .....); }int threadfn(void *data) {static int count 0 ;int args *(int *)data;printk(KERN_INFO enter thead_fn);while(1){msleep(2*1000);printk(KERN_INFO threadfn data: %d, count: %d,args , count);queue_work(workqueue,work1);//将任务放到自己创建的工作队列上去执行queue_work(workqueue,work2);} } static int __init test_kobj_init(void) {workqueue create_workqueue(create_new_work_queue);INIT_WORK(work1,do_work1);INIT_WORK(work2,do_work2);struct task_struct * thread kthread_create( threadfn,(void * )data,mythread);if(thread ! NULL){printk(KERN_INFO thread create success);wake_up_process(thread);}else{printk(KERN_ERR thread create err);}return 0; }static void __exit test_kobj_exit(void) {printk(KERN_INFO test_kobj_exit );destroy_workqueue(workqueue);return; }module_init(test_kobj_init); module_exit(test_kobj_exit);MODULE_AUTHOR(copy other auther); MODULE_LICENSE(GPL); 在使用如下函数时注意事项 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上添加工作任务 常见的应用场景 work_struct 是 Linux 内核中用于处理异步任务的机制它允许内核将任务推迟到工作队列中由工作线程在适当的时候执行。work_struct 可以处理多种类型的任务以下是一些常见的应用场景 1. 中断处理 中断处理程序需要快速完成以避免过长时间占用 CPU。如果中断处理程序需要执行一些耗时的操作可以将这些操作推迟到工作队列中执行。例如 static void my_interrupt_handler(int irq, void *dev_id) {struct work_struct *work (struct work_struct *)dev_id;queue_work(my_workqueue, work); } 2. 定时任务 如果需要在特定时间后执行某些任务可以使用 queue_delayed_work 将任务推迟到工作队列中。例如 static void my_delayed_work_handler(struct work_struct *work) {printk(KERN_INFO Delayed work handler called\n); }static int __init my_module_init(void) {my_workqueue create_workqueue(my_workqueue);if (!my_workqueue) {return -ENOMEM;}struct my_work *my_work kmalloc(sizeof(struct my_work), GFP_KERNEL);if (!my_work) {return -ENOMEM;}INIT_DELAYED_WORK(my_work-work, my_delayed_work_handler);queue_delayed_work(my_workqueue, my_work-work, msecs_to_jiffies(1000)); // 延迟 1 秒return 0; } 3. 文件系统操作 在文件系统操作中某些耗时的操作可以推迟到工作队列中执行。例如文件系统的同步操作可以使用工作队列来处理 static void my_sync_handler(struct work_struct *work) {printk(KERN_INFO File system sync handler called\n);// 执行文件系统同步操作 }static int __init my_module_init(void) {my_workqueue create_workqueue(my_workqueue);if (!my_workqueue) {return -ENOMEM;}struct my_work *my_work kmalloc(sizeof(struct my_work), GFP_KERNEL);if (!my_work) {return -ENOMEM;}INIT_WORK(my_work-work, my_sync_handler);queue_work(my_workqueue, my_work-work);return 0; } 4. 设备驱动程序 在设备驱动程序中某些操作如硬件初始化、数据传输等可以推迟到工作队列中执行。例如 static void my_device_init_handler(struct work_struct *work) {printk(KERN_INFO Device initialization handler called\n);// 执行设备初始化操作 }static int __init my_module_init(void) {my_workqueue create_workqueue(my_workqueue);if (!my_workqueue) {return -ENOMEM;}struct my_work *my_work kmalloc(sizeof(struct my_work), GFP_KERNEL);if (!my_work) {return -ENOMEM;}INIT_WORK(my_work-work, my_device_init_handler);queue_work(my_workqueue, my_work-work);return 0; } 5. 网络协议栈 在网络协议栈中某些操作如数据包处理、连接管理等可以推迟到工作队列中执行。例如 static void my_packet_handler(struct work_struct *work) {printk(KERN_INFO Packet handler called\n);// 处理数据包 }static int __init my_module_init(void) {my_workqueue create_workqueue(my_workqueue);if (!my_workqueue) {return -ENOMEM;}struct my_work *my_work kmalloc(sizeof(struct my_work), GFP_KERNEL);if (!my_work) {return -ENOMEM;}INIT_WORK(my_work-work, my_packet_handler);queue_work(my_workqueue, my_work-work);return 0; } 6. 用户空间请求 在处理用户空间请求时某些操作可以推迟到工作队列中执行。例如 static void my_user_request_handler(struct work_struct *work) {printk(KERN_INFO User request handler called\n);// 处理用户请求 }static int __init my_module_init(void) {my_workqueue create_workqueue(my_workqueue);if (!my_workqueue) {return -ENOMEM;}struct my_work *my_work kmalloc(sizeof(struct my_work), GFP_KERNEL);if (!my_work) {return -ENOMEM;}INIT_WORK(my_work-work, my_user_request_handler);queue_work(my_workqueue, my_work-work);return 0; } 注意事项 工作函数的执行环境工作函数在工作线程中执行允许睡眠因此可以执行耗时操作。     工作队列的销毁在模块退出时确保使用 flush_workqueue 等待所有工作完成然后使用 destroy_workqueue 销毁工作队列。     工作项的释放在工作函数中确保释放分配的工作项避免内存泄漏。 通过这些示例你可以看到 work_struct 可以处理多种类型的任务包括中断处理、定时任务、文件系统操作、设备驱动程序、网络协议栈和用户空间请求等。这使得 work_struct 成为内核中处理异步任务的强大工具。
http://www.w-s-a.com/news/149958/

相关文章:

  • 为什么在百度搜不到我的网站电商网站开发过程
  • 什么是网站反链网页设计页面链接
  • 佛山企业网站制作韩国seocaso
  • 微信公司网站vue做社区网站
  • 蒙阴网站优化五核网站建设
  • 企业微商城网站建设wordpress新闻是哪个表
  • 重庆网站开发培训机构电商网站创办过程
  • 企业建网站得多少钱长沙财优化公司
  • 网站开发api平台扒完网站代码之后怎么做模板
  • PHP网站建设选择哪家好动画设计师月薪多少
  • 网站如何做市场推广网站开发主要步骤
  • 浏览器正能量网站网页文章导入wordpress
  • 江西中国建设银行网站首页永久免费自助建网站
  • 创建自己网站的步骤吸引人的微信软文
  • 网站建设与网页设计论述题软件开发公司在哪里
  • 二级网站建设方案模板亚马逊网站建设案例
  • 网站开发兼职团队门户网站如何制作
  • 高州市网站建设开发区招聘信息
  • 上海专业网站制作设计公司企业邮箱怎样注册
  • 网站建设在商标第几类网站建设 设计创意
  • 做一网站APP多少钱重庆中色十二冶金建设有限公司网站
  • 网上做效果图网站有哪些软件徐州泉山区建设局网站
  • 凯里网站制作网站篡改搜索引擎js
  • 如何使用凡科建设网站武安城乡建设网站
  • 网站建设网站及上传wordpress火车头发布
  • 有没有做网站的团队电脑版传奇网站
  • 建立企业网站公司医疗创意小产品设计
  • 深圳 做网站 车公庙免费的招标网有哪些
  • 网站在那里备案成都成华区网站建设
  • 做网站选哪家好搜索引擎优化的目标体系包括哪些