Linux學習筆記之內核線程
阿新 • • 發佈:2017-09-23
出了 freeze rest eas time 進程 來看 inf span
中是否有內容,如果有,就根據鏈表的元素去創建一個內核線程。而函數kthread_create()會向鏈表kthread_create_list中插入元素(代碼這裏就不貼了)。
本文旨在簡單介紹一下Linux內核線程:
先舉個例子:
不插U盤,在Linux命令行中輸入:ps -el;然後插上U盤,再次輸入:ps -el
會發現多出了下面一行(當然還會有其他的,比如scsi相關的):
1 F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 2 1 S 0 2749 2 0 80 0 - 0 - ? 00:00:00 usb-storage
usb-storage 就是U盤驅動程序(驅動程序是動態加載的)起來之後,由內核創建的內核線程。下面我們就來看一下它是如何被創建的。有關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
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 }
U盤驅動程序的內核線程是如何被創建的呢? 就是通過下面這段代碼(位於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學習筆記之內核線程