工作队列work queuedemo_task

Linux内核实践之工作队列_bullbat的博客-CSDN博客_内核工作队列  这个资料讲到了队列的两种使用方法 
域名停靠  这个资料中讲到了任务的移除 
参见中断子系统中的下半部内容 
工作队列实际是由一个内核线程去维护和执行队列上的任务的。 
当系统启动后,内核为每一个cpu都创建一个工作队列(即缺省的工作队列),每个工作队列由一个内核线程去维护,线程的名字叫[kworker/0]表示cpu 0 的线程, 
[kworker/1]表示cpu1的线程。所以有几个cpu就可以看到几个[kworker/xxx]. 
当系统缺省的工作队列负载太大的时候,我们可以选择自己创建一个工作队列。 
在老内核中,每创建一个工作队列,就要为每一个cpu新建一个内核线程。这样当你创建的工作队列很多的时候会消耗很多的调度资源,包括内存。。,线程名称就是你的创建工作队列的时候 
填入的name,如果是多cpu,比如3个,当你创建这个工作队列以后,你就会看到有[name/0],[name/1],[name/2]这样3个内核线程。这样非常不利于并发。

以下内容摘自:中断服务下半部之工作队列详解 - arm-linux - 博客园 
这么做会在每个处理器上都创建一个工作者线程,所以只有在你明确了必须要靠自己的一套线程来提高性能的情况下,再创建自己的工作队列。创建一个新的任务队列和与之相关的工作者线程,只需调用一个简单的函数:create_workqueue。这个函数会创建所有的工作者线程(系统中的每个处理器都有一个)并且做好 所有开始处理工作之前的准备工作。name参数用于该内核线程的命名。对于具体的线程会更加CPU号添加上序号。create_workqueue和create_singlethread_workqueue都是创建一个工作队列,但是差别在于create_singlethread_workqueue可以指定为此工作队列只创建一个内核线程,这样可以节省 资源,无需发挥SMP的并行处理优势。

新内核中,这种每创建一个工作队列就要为每一个cpu都创建一个内核线程的做法得到的改变。但是系统启动的时候任然会为每个cpu创建一个缺省的工作队列,并各自由一个内核线程去维护。 
当我们要创建一个新的工作队列的时候,只在某个cpu上创建一个内核线程去维护这个工作队列。 
正确的使用队列以及在工作队列中传参 
一。使用内核缺省的工作队列:



  1. 1.struct work_struct work; //定义一个work结构体,即队列项
  2. 2.任务函数:static void demo_task_monitor(struct work_struct *task_work)
  3. 可以传入自己的私有结构体
  4.    struct xxx*test = container_of(work, struct xxx, task_work);
  5. 3.将任务结构体初始化,绑定任务
  6. INIT_WORK(&work,demo_task_monitor);
  7. 4.将任务加入缺省队列,同时开启任务:此时任务开始被调度执行
  8. schedule_work(&work);
  9. static inline bool schedule_work(struct work_struct *work)
  10. {
  11. return queue_work(system_wq, work);//可以看到内部仍然是一个queue_work,只不过将对队列项加在了系统默认的内核队列中了
  12. }
  13. 5.从工作队列中删除这个任务
  14. cancel_work_sync(&work);//remove task from work queue
  15. 6.再次执行这个任务:
  16. schedule_work(&work);//其实是对queue_work的一次封装,指定了内核的缺省队列

二。自己创建工作队列,并且将任务加入自己的工作队列。

  1. struct workqueue_struct        *workqueue; //定义一个工作队列结构体
  2. struct work_struct                 work;//定义一个任务结构体
  3. 1.与使用内核缺省的工作队列不同,这种方式首先要自己先建立一个工作队列
  4. workqueue = create_workqueue("task_xx");
  5. 2.初始化一个任务
  6. INIT_WORK(&work, demo_task);//将任务结构体初始化,绑定任务
  7. 3,加入自己创建的队列,并开始调度
  8. queue_work(dev->workqueue, &dev->work);
  9. 4,从工作队列中删除这个任务
  10. cancel_work_sync(&work);//remove task from work queue
  11. 5,销毁这个工作队列:
  12. destroy_workqueue(struct workqueue_struct *wq);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值