天天看點

工作隊列work queue

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. 1.struct work_struct work; //定義一個work結構體,即隊列項

  2. 2.任務函數:static void cxd2856_task_monitor(struct work_struct *nim_work)

  3. 可以傳入自己的私有結構體

  4. 3.将任務結構體初始化,綁定任務

  5. INIT_WORK(&work,cxd2856_task_monitor);

  6. 4.将任務加入預設隊列,同時開啟任務:此時任務開始被排程執行

  7. schedule_work(&work);

  8. static inline bool schedule_work(struct work_struct *work)

  9. {

  10. return queue_work(system_wq, work);//可以看到内部仍然是一個queue_work,隻不過将對隊列項加在了系統預設的核心隊列中了

  11. }

  12. 5.從工作隊列中删除這個任務

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

  14. 6.再次執行這個任務:

  15. 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, nim_s3281_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);

繼續閱讀