linux内核workqueue的两种调度方式

原文地址:http://blog.chinaunix.net/uid-20703572-id-1889214.html

 

第一种使用schedule_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);


第二种使用queue_work和定时器自动调度:

#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;
};


struct timer_data test_data;
struct timer_data test_data1;
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;


void test_timer_fn(unsigned long arg)
{
        struct timer_data *data = (struct timer_data *)arg;


        unsigned long j = jiffies;
        data->timer.expires += 2 * HZ;
        data->prev_jiffies = j;
        add_timer(&data->timer);


        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);
}


void test_timer_fn1(unsigned long arg)
{
        struct timer_data *data = (struct timer_data *)arg;
        unsigned long j = jiffies;
        data->timer.expires += 3 * HZ;
        data->prev_jiffies = j;
        add_timer(&data->timer);


        //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);
}


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));
}


int wq_init(void)
{
        unsigned long j = jiffies;


        printk("jiffies: %lu\n", jiffies);
        atomic_set(&wq_run_times, 0);


        init_timer(&test_data.timer);
        test_data.loops = 0;
        test_data.prev_jiffies = j;
        test_data.timer.function = test_timer_fn;
        test_data.timer.data = (unsigned long)(&test_data);
        test_data.timer.expires = j + 2 * HZ;
        add_timer(&test_data.timer);


        init_timer(&test_data1.timer);
        test_data1.loops = 0;
        test_data1.prev_jiffies = j;
        test_data1.timer.function = test_timer_fn1;
        test_data1.timer.data = (unsigned long)(&test_data1);
        test_data1.timer.expires = j + 3 * HZ;
        add_timer(&test_data1.timer);


        test_workqueue = create_singlethread_workqueue("test-wq");
        printk("test-wq init success\n");
        printk("jiffies: %lu\n", jiffies);
        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)

注意:不能在同一时间内向一个工作队列添加相同的任务

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值