標籤:核心 c99 create warning inux one res strong 驅動
本文旨在簡單介紹一下Linux核心線程:
先舉個例子:
不插隨身碟,在Linux命令列中輸入:ps -el;然後插上隨身碟,再次輸入:ps -el
會發現多出了下面一行(當然還會有其他的,比如scsi相關的):
1 F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD2 1 S 0 2749 2 0 80 0 - 0 - ? 00:00:00 usb-storage
usb-storage 就是隨身碟驅動程式(驅動程式是動態載入的)起來之後,由核心建立的核心線程。下面我們就來看一下它是如何被建立的。有關usb-storage的完整內容,以後學習USB驅動時再詳解,今天只討論核心是如何管理核心線程的建立的。
在啟動過程中,Linux2.6.22.6/init/main.c::rest_init()會建立另外2個進程(1號進程kernel_init和2號進程kthreadd),今天我們要討論的就是2號進程kthreadd,它是所有核心線程(比如上面的usb-storage)的父進程。
1 static void noinline __init_refok rest_init(void) 2 __releases(kernel_lock) 3 { 4 int pid; 5 6 kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); // 建立1號進程 7 numa_default_policy(); 8 pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); // 建立2號進程 kthreadd 9 kthreadd_task = find_task_by_pid(pid);10 unlock_kernel();11 ....12 }
kthreadd()位於Linux2.6.22.6/kernel/kthread.c,今天我們主要就是分析這支檔案。
kthreadd進程被建立之後就開始運行,我們看到他有一個死迴圈(for),他會一直去判斷鏈表kthread_create_list中是否有內容,如果有,就根據鏈表的元素去建立一個核心線程。而函數kthread_create()會向鏈表kthread_create_list中插入元素(代碼這裡就不貼了)。
1 int kthreadd(void *unused) 2 { 3 /* Setup a clean context for our children to inherit. */ 4 kthreadd_setup(); 5 6 current->flags |= PF_NOFREEZE; 7 8 for (;;) { 9 set_current_state(TASK_INTERRUPTIBLE); // 設定進程狀態: 可中斷的等待狀態10 if (list_empty(&kthread_create_list)) // 如果鏈表為空白11 schedule();12 13 __set_current_state(TASK_RUNNING);14 15 spin_lock(&kthread_create_lock);16 while (!list_empty(&kthread_create_list)) {17 struct kthread_create_info *create;18 19 create = list_entry(kthread_create_list.next,20 struct kthread_create_info, list);21 list_del_init(&create->list);22 spin_unlock(&kthread_create_lock);23 24 create_kthread(create); // 他會調用kernel_thread完成真正的核心線程建立25 26 spin_lock(&kthread_create_lock);27 }28 spin_unlock(&kthread_create_lock);29 }30 31 return 0;32 }
隨身碟驅動程式的核心線程是如何被建立的呢? 就是通過下面這段代碼(位於Linux2.6.22.6/driver/usb/storage/usb.c):
1 /* Start up our control thread */2 th = kthread_create(usb_stor_control_thread, us, "usb-storage"); // 3 if (IS_ERR(th)) {4 printk(KERN_WARNING USB_STORAGE 5 "Unable to start control thread\n");6 return PTR_ERR(th);7 }
下面通過一張圖來總結一下:
Linux學習筆記之核心線程