fork() 是「Process Creation」議題的重要里程碑:提到 system call 代表著我們的研究要正式進入 kernel space 的層面了。
值得附帶一提的是,sys_fork 是一個 machine-dependent 的 system call,以 i386 為例,其實作位於 linux/arch/i386/kernel/process.c。*1
Operating System 端的觀念
sys_fork 是非常重要的 system call,從作業系統的角度來解釋的話,這就是「建立 process」的主要 system call。當外部程式(即 ELF image)被使用者鍵入指令後,shell 便會呼叫 fork() 系統呼叫,並透過作業系統的 fork system call 來產生新的 process,以執行此外部程式。這種類型的 fork 也稱做 spawn。
可參考先前 Jollen 所分享的「Process Creation」前二則日記,以便了解 spawn、fork、exec 等等觀念:
強烈建議您先閱讀以上二則日記,並了解 user-space 端的 process 觀念後,再繼續往下學習,才能更容易「感受」fork system call 的觀念。
Linux 端的觀念
Linux 並沒有 spawn system call,根據「Process Creation」日記的解說,Linux 下的 fork + exec 等於 spawn。而其中最核心的觀念則是在於 fork 的實作,也就是「如何產生新的 process」。
Linux 以 sys_fork 或 sys_clone 來產生新的 process,而這二個 system call 最後都會呼叫到 do_fork() 函數,do_fork() 是 Linux 主要的 fork-routine。繼續探討 do_fork() 時,便會接觸到以下二個重要議題:
關於更深入的 fork(),我們就先在此打住,下篇日記《核心實作》再做介紹。以下是 sys_fork() 與 sys_clone() 的程式碼(Linux 2.6.17.7::arch/i386/kernel/process.c):
asmlinkage int sys_fork(struct pt_regs regs) { return do_fork(SIGCHLD, regs.esp, ®s, 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, ®s, 0, parent_tidptr, child_tidptr); }
do_fork() 的函數原型:
/* * Ok, this is the main fork-routine. * * It copies the process, and if successful kick-starts * it and waits for it to finish using the VM if required. */ long do_fork(unsigned long clone_flags, unsigned long stack_start, struct pt_regs *regs, unsigned long stack_size, int __user *parent_tidptr, int __user *child_tidptr);
clone_flags 是 do_fork() 觀念的核心,也是很有趣的議題。
Also See |
|
Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue
您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw