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

struct work_struct my_work;

INIT_WORK(&my_work, my_func, “Jack”);

queue_work(my_wq, &my_work);

destroy_workqueue(my_wq);

2、2.6.20~2.6.??

自2.6.20起,工作队列的数据结构发生了一些变化,使用时不能沿用旧的方法。

数据结构:

typedef void (*work_func_t)(struct work_struct *work);

struct work_struct {

atomic_long_t data;

struct list_head entry;

work_func_t func;

};

与2.6.19之前的版本相比,work_struct瘦身不少。粗粗一看,entry和之前的版本相同,func和data发生了变化,另外并无其他的变量。

entry我们不去过问,这个和以前的版本完全相 同。data的类型是atomic_long_t,这个类型从字面上看可以知道是一个原子类型。第一次看到这个变量时,很容易误认为和以前的data是同 样的用法,只不过类型变了而已,其实不然,这里的data是之前版本的pending和wq_data的复合体,起到了以前的pending和 wq_data的作用。

func的参数是一个work_struct指针,指向的数据就是定义func的work_struct。

看到这里,会有两个疑问,第一,如何把用户的数据作为参数传递给func呢?以前有void *data来作为参数,现在好像完全没有办法做到;第二,如何实现延迟工作?目前版本的work_struct并没有定义timer。

解决第一个问题,需要换一种思路。2.6.20版本之后使用工作队列需要把work_struct定义在用户的数据结构中,然后通过container_of来得到用户数据。具体用法可以参考稍后的实作。

对于第二个问题,新的工作队列把timer拿掉的用 意是使得work_struct更加单纯。首先回忆一下之前版本,只有在需要延迟执行工作时才会用到timer,普通情况下timer是没有意义的,所以 之前的做法在一定程度上有些浪费资源。所以新版本中,将timer从work_struct中拿掉,然后又定义了一个新的结构delayed_work用 于处理延迟执行:

struct delayed_work {

struct work_struct work;

struct timer_list timer;

};

下面把API罗列一下,每个函数的解释可参考之前版本的介绍或者之后的实作:

1) INIT_WORK(struct work_struct *work, work_func_t func)

2) INIT_DELAYED_WORK(struct delayed_work *work, work_func_t func)

3) int schedule_work(struct work_struct *work)

4) int schedule_delayed_work(struct delayed_work *work, unsigned long delay)

5) struct workqueue_struct *create_workqueue(const char *name)

6) int queue_work(struct workqueue_struct *wq, struct work_struct *work)

7) int queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *work, unsigned long delay)

8) void flush_scheduled_work(void)

9) void flush_workqueue(struct workqueue_struct *wq)

10) int cancel_delayed_work(struct delayed_work *work)

11) void destroy_workqueue(struct workqueue_struct *wq)

其中,1), 2), 4) ,7)和以前略有区别,其他用法完全一样。

实作:

struct my_struct_t {

char *name;

struct work_struct my_work;

};

void my_func(struct work_struct *work)

{

struct my_struct_t *my_name = container_of(work, struct my_struct_t, my_work);

printk(KERN_INFO “Hello world, my name is %s!\n”, my_name->name);

}

struct workqueue_struct *my_wq = create_workqueue(“my wq”);

struct my_struct_t my_name;

my_name.name = “Jack”;

INIT_WORK(&(my_name.my_work), my_func);

queue_work(my_wq, &my_work);

destroy_workqueue(my_wq);0b1331709591d260c1c78e86d0c51c18.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值