您的位置:首页 > 产品设计 > UI/UE

工作队列work queue

2018-02-16 00:05 113 查看
http://blog.csdn.net/bullbat/article/details/7410563 这个资料讲到了队列的两种使用方法 
http://www.itnose.net/detail/6463690.html 这个资料中讲到了任务的移除 
参见中断子系统中的下半部内容 
工作队列实际是由一个内核线程去维护和执行队列上的任务的。 
当系统启动后,内核为每一个cpu都创建一个工作队列(即缺省的工作队列),每个工作队列由一个内核线程去维护,线程的名字叫[kworker/0]表示cpu 0 的线程, 
[kworker/1]表示cpu1的线程。所以有几个cpu就可以看到几个[kworker/xxx]. 
当系统缺省的工作队列负载太大的时候,我们可以选择自己创建一个工作队列。 
在老内核中,每创建一个工作队列,就要为每一个cpu新建一个内核线程。这样当你创建的工作队列很多的时候会消耗很多的调度资源,包括内存。。,线程名称就是你的创建工作队列的时候 
填入的name,如果是多cpu,比如3个,当你创建这个工作队列以后,你就会看到有[name/0],[name/1],[name/2]这样3个内核线程。这样非常不利于并发。以下内容摘自:http://www.cnblogs.com/armlinux/archive/2010/11/19/2396892.html 
这么做会在每个处理器上都创建一个工作者线程,所以只有在你明确了必须要靠自己的一套线程来提高性能的情况下,再创建自己的工作队列。创建一个新的任务队列和与之相关的工作者线程,只需调用一个简单的函数:create_workqueue。这个函数会创建所有的工作者线程(系统中的每个处理器都有一个)并且做好 所有开始处理工作之前的准备工作。name参数用于该内核线程的命名。对于具体的线程会更加CPU号添加上序号。create_workqueue和create_singlethread_workqueue都是创建一个工作队列,但是差别在于create_singlethread_workqueue可以指定为此工作队列只创建一个内核线程,这样可以节省 资源,无需发挥SMP的并行处理优势。新内核中,这种每创建一个工作队列就要为每一个cpu都创建一个内核线程的做法得到的改变。但是系统启动的时候任然会为每个cpu创建一个缺省的工作队列,并各自由一个内核线程去维护。 
当我们要创建一个新的工作队列的时候,只在某个cpu上创建一个内核线程去维护这个工作队列。 
正确的使用队列以及在工作队列中传参 
一。使用内核缺省的工作队列:
1.struct work_struct work;    //定义一个work结构体,即队列项

2.任务函数:static void cxd2856_task_monitor(struct work_struct *nim_work)


可以传入自己的私有结构体


3.将任务结构体初始化,绑定任务

INIT_WORK(&work,cxd2856_task_monitor);

4.将任务加入缺省队列,同时开启任务:此时任务开始被调度执行

schedule_work(&work);

static inline bool schedule_work(struct work_struct *work)

{

return queue_work(system_wq, work);//可以看到内部仍然是一个queue_work,只不过将对队列项加在了系统默认的内核队列中了

}

5.从工作队列中删除这个任务

cancel_work_sync(&work);//remove task from work queue

6.再次执行这个任务:

schedule_work(&work);//其实是对queue_work的一次封装,指定了内核的缺省队列

二。自己创建工作队列,并且将任务加入自己的工作队列。
struct workqueue_struct        *workqueue; //定义一个工作队列结构体

struct work_struct                 work;//定义一个任务结构体

1.与使用内核缺省的工作队列不同,这种方式首先要自己先建立一个工作队列

workqueue = create_workqueue("task_xx");

2.初始化一个任务

INIT_WORK(&work, nim_s3281_task);//将任务结构体初始化,绑定任务

3,加入自己创建的队列,并开始调度

queue_work(dev->workqueue, &dev->work);

4,从工作队列中删除这个任务

cancel_work_sync(&work);//remove task from work queue

5,销毁这个工作队列:

destroy_workqueue(struct workqueue_struct *wq);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: