Search Google

Thursday, June 19, 2008

[Process Management] Process/Thread Creation Part 2

專門用語:

  • 使用打字機(Courier New)字體表示原始碼。
  • task/process即為Linux中的thread。
  • 文中的Linux與Linux kernel指的皆為作業系統核心。
  • 使用斜體字型標示Linux中的資料結構,變數或函式名稱。

Kernel版本:
  • v2.6.24.3

User thread:
應用程式使用fork,vfork,或clone函式建立新的user threads,這些函式分別透過Linux system call呼叫sys_forksys_vfork,或sys_clone kernel function建立新threads,而sys_forksys_vfork,與sys_clone共同呼叫的函式為do_fork1

asmlinkage int sys_fork(struct pt_regs regs)
{
return do_fork(SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
}


asmlinkage int sys_clone(struct pt_regs regs)
{
unsigned long clone_flags;
unsigned long newsp;
int __user *parent_tidptr, *child_tidptr;

clone_flags = regs.ebx;
newsp = regs.ecx;
parent_tidptr = (int __user *)regs.edx;
child_tidptr = (int __user *)regs.edi;
if (!newsp)
newsp = regs.esp;
return do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr);
}


asmlinkage int sys_vfork(struct pt_regs regs)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0, NULL, NULL);
}

上面三個函式都只為新thread準備好task_structtask_thread_info,與堆疊空間,至於新的thread該執行哪些程式碼則毫無著墨。應用程式一般以呼叫執行檔的方式啟動2,便是將執行檔的binary內容讀取到記憶體中執行,這個步驟則是透過sys_execve函式呼叫do_execve函式完成,因此一般建立新user thread時sys_execve會搭配於task_structtask_thread_info,與堆疊空間建制完成之後執行將執行檔載入記憶體。

asmlinkage int sys_execve(struct pt_regs regs)
{
int error;
char * filename;

filename = getname((char __user *) regs.ebx);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
error = do_execve(filename,
(char __user * __user *) regs.ecx,
(char __user * __user *) regs.edx,
&regs);
if (error == 0) {
task_lock(current);
current->ptrace &= ~PT_DTRACE;
task_unlock(current);
/* Make sure we don't return using sysenter.. */
set_thread_flag(TIF_IRET);
}
putname(filename);
out:
return error;
}




1 kernel_thread最後也是呼叫do_fork
2 例如開啟Firefox網頁瀏覽器。

No comments: