1. 程式人生 > >3.x 核心新工作佇列kworker/n ;current標頭檔案,unrecognized ELF data encoding 0:

3.x 核心新工作佇列kworker/n ;current標頭檔案,unrecognized ELF data encoding 0:

今天在linux-3.9.5上想用current ->comm,current->pid時,編譯不通過,

需新增:

 #include <linux/kthread.h>

#include<asm/current.h>

之後可以正常編譯通過,但是重複多次編譯時,會出下如下錯誤:

unrecognized ELF data encoding 0: 

這是編譯器cache的問題:

需執行:

ccache -c 

工作佇列:

雖然自從2.6.0之後,Linux對work queue進行了優化,但是kernel用到create_workqueue的模組越來越多,而呼叫create_workqueue會在每個cpu上都建立一個work_thread, 每個cpu都分配一個cpu_workqueue_struct以及workqueue_struct,而如果沒被queue_work的話根本沒機會工作,這樣仍然相當浪費記憶體資源,而且加重了cpu loading。另外,同一個work queue上的每個work都是按照序列執行的,假如其中一個work的排程程式睡眠了,那麼後面的work也將無法工作。

自從2.6.36以後,work queue的機制發生了很大變化,所有的work queue都被合併成

一個work queue,work thread也不是和work queue一一關聯,work何時工作緊緊按照工作的重要性以及時間緊迫性來劃分。也就是說新機制是按照cpu數量來建立work thread,而不是work queue。


例:工作佇列(列印預設工作佇列)--linux-3.9上預設工作執行緒名是kworker/n ,不再是2.6系列上的 event/

#include <linux/init.h>  
#include <linux/module.h>  
#include <linux/fs.h>  
#include <linux/kernel.h>  
#include <linux/slab.h>  
#include <linux/workqueue.h>  
#include <asm/current.h>  
#include <linux/kthread.h>  
#include <linux/sched.h>  
static void do_declarework(struct work_struct *work){  
  printk(KERN_EMERG "declarework: [%s:%d]\n",current->comm,current->pid);  
//列印執行這個工作work的執行緒名和pid

}  
static void do_work(struct work_struct *work){  
  printk(KERN_EMERG "init_work: [%s:%d]\n",current->comm,current->pid);  
   //列印執行這個工作work的執行緒名和pid
}  
static void do_delaywork(struct work_struct *work){  
  printk(KERN_EMERG "delaywork: [%s:%d]\n",current->comm,current->pid);  
    //列印執行這個工作work的執行緒名和pid

}  
struct work_struct my-work;  
struct delayed_work my-delaywork;  
struct workqueue_struct *mywq;  
static int __init kerneladdr(void){  
        DECLARE_WORK(my-declarework,do_declarework);  //宣告並初始化一個工作
  
        INIT_WORK(&my-work,do_work);    //初始化一下工作my-work
  
        INIT_DELAYED_WORK(&my-delaywork,do_delaywork);  //初始化一個延時工作my-delaywork
  
        schedule_work(&my-declarework);  
        schedule_work(&my-work);  
        schedule_delayed_work(&my-delaywork,5);  
        flush_scheduled_work();  //flush_workqueue(keventd_wq);
//插入一個work,並等待這個work執行完成。
  
    mywq=alloc_workqueue("mywq",0,0);  //舊版為create_workqueue("mywq");
//建立一個工作佇列,舊版會給每個CPU都建立一下執行緒. 新的cmwq不會建立執行緒.
    queue_work(mywq,&my-work);  
    flush_workqueue(mywq);  
        return 0;  
}  
  
static void __exit kerneladdr_exit(void){  
    printk(KERN_ALERT"Entry kerneladdr_exit!\n");  
    destroy_workqueue(mywq);  
}  
MODULE_LICENSE("GPL");  
module_init(kerneladdr);  

module_exit(kerneladdr_exit);  

舊版wq原理如下:


新版cmwq原理: