linux work queue的两种调度方式
2016-09-25 17:26
363 查看
第一种使用schedule_work手动调度:
第二种使用queue_work和定时器自动调度:
注意:不能在同一时间内向一个工作队列添加相同的任务
#include<linux/init.h> #include<linux/module.h> #include<linux/timer.h> #include<linux/time.h> #include<linux/workqueue.h> #include<asm/atomic.h> #include<linux/delay.h> MODULE_AUTHOR("lcw"); MODULE_LICENSE("GPL"); struct timer_data test_data; struct timer_data test_data1; static struct workqueue_struct*test_workqueue; atomic_t wq_run_times; unsigned int failed_cnt = 0; static void do_work(void*); static void do_work1(void*); static struct work_struct test_work; static struct work_struct test_work1; // 工作函数中再次手动调度队列,使其不断执行 static void do_work(void*arg) { printk("goodbye\n"); mdelay(2000); schedule_work(&test_work1); } static void do_work1(void*arg) { printk("hello world\n"); mdelay(2000); schedule_work(&test_work); } int wq_init(void) { INIT_WORK(&test_work, do_work); INIT_WORK(&test_work1, do_work1) test_workqueue = create_singlethread_workqueue("test-wq"); schedule_work(&test_work); printk("test-wq init success\n"); printk("jiffies: %lu\n", jiffies); return 0; } void wq_exit(void) { destroy_workqueue(test_workqueue); printk("wq exit success\n"); } module_init(wq_init); module_exit(wq_exit); |
#include linux/init.h> #include linux/module.h> #include linux/moduleparam.h> #include linux/time.h> #include linux/timer.h> #include linux/workqueue.h> #include asm/atomic.h> MODULE_AUTHOR("lcw"); MODULE_LICENSE("GPL"); struct timer_data { struct timer_list timer; struct workqueue_struct *work_queue; unsigned long prev_jiffies; unsigned int loops; }; static struct timer_list timer1; static struct timer_list timer2; static void do_work(void *); static DECLARE_WORK(test_work, do_work, NULL); static DECLARE_WORK(test_work1, do_work, NULL); static struct workqueue_struct *test_workqueue; atomic_t wq_run_times; unsigned int failed_cnt = 0; // 定时器1超时函数 void test_timer_fn1(unsigned long arg) { struct timer_data *data = (struct timer_data *)arg; mod_timer(&timer1, jiffies+HZ/100); // 设置超时时间 1\100s if (queue_work(test_workqueue, &test_work)== 0) { printk("Timer (0) add work queue failed\n"); (*(&failed_cnt))++; } data->loops++; printk("timer-0 loops: %u\n", data->loops); } // 定时器2超时函数 void test_timer_fn2(unsigned long arg) { struct timer_data *data = (struct timer_data *)arg; mod_timer(&timer2, jiffies+HZ/100); // 设置超时时间 1\100s //if (queue_work(test_workqueue, &test_work)== 0) { if (queue_work(test_workqueue, &test_work1)== 0) { printk("Timer (1) add work queue failed\n"); (*(&failed_cnt))++; } data->loops++; printk("timer-1 loops: %u\n", data->loops); } // work func void do_work(void*arg) { //原子计数值加一 atomic_inc(&wq_run_times); printk("====work queue run times: %u====\n", atomic_read(&wq_run_times)); printk("====failed count: %u====\n",*(&failed_cnt)); } // init int wq_init(void) { //原子计数值初始化 atomic_set(&wq_run_times, 0); // work queue test_workqueue = create_singlethread_workqueue("test-wq"); // timer1 init_timer(&timer1); timer1.function= test_timer_fn1; add_timer(&timer1); // timer2 init_timer(&timer2); timer2.function= test_timer_fn1; add_timer(&timer2); //设置超时时间,启动定时器 mod_timer(&timer1, jiffies+HZ/100); // 设置超时时间 1\100s mod_timer(&timer2, jiffies+HZ/100); // 设置超时时间 1\100s return 0; } void wq_exit(void) { del_timer(&test_data.timer); del_timer(&test_data1.timer); destroy_workqueue(test_workqueue); printk("wq exit success\n"); } module_init(wq_init); module_exit(wq_exit) |
相关文章推荐
- Linux文件目录操作相关命令
- Linux(1)
- Centos 7 系统安装完毕修改网卡名为eth0
- /dev/null 2>&1
- linux ls -l 详解
- Linux -- 文件统计常用命令
- Linux最常用的20条命令
- Linux -- 文件统计常用命令
- Linux用户和组的操作
- linux 无法访问域名
- Linux 6上使用UDEV绑定共享存储
- Linux
- Linux常用命令:sed
- Centos 6 上安装R-3.3.1
- Linux文件系统操作命令
- Linux软链接和硬链接
- Linux Ubuntu 能PING IP但不能PING主机域名的解决方法
- 4 个最好的 Linux 引导程序
- Linux作业8
- Linux系统常用指令、管道、find 文件查找指令