进程控制1--fork vfork函数
linux系統(tǒng)調(diào)用fork()創(chuàng)建一個和當前進程完全相同的拷貝進程,其中父進程和子進程的代碼段,堆棧段,數(shù)據(jù)段均獨立
?
進程必須的4要點:
a.要有一段程序供該進程運行
b.進程專用的系統(tǒng)堆棧空間。
c.進程控制塊,在linux中具體實現(xiàn)是task_struct
d.有獨立的存儲空間。
當一個進程缺少其中一個條件時候,我們稱其為線程。
?
1.先看fork()的原型 :
?
#include<sys/types.h> /* 提供類型pid_t的定義 */
#include<unistd.h> /* 提供函數(shù)的定義 */
pid_t fork(void);
返回: 父進程中執(zhí)行則返回子進程PID,子進程中執(zhí)行返回0
?
現(xiàn)在進行一個例子,創(chuàng)建一個子進程,然后根據(jù)返回的 PID進行識別:
[cpp]?view plaincopy
弄好后,在linux中鍵入:
?
$ gcc test.c -o test
$ ./test
?
在本次試驗中
?
I am the parent process,my count is 1,my process ID is 3196
I am the child process, my count is 0,my process ID is 3776
?
?從代碼里面可以看出2者的pid不同,內(nèi)存資源count是值得復(fù)制,父進程改變了count的值,而子進程中的count沒有被改變。有人認為這樣大批量的復(fù)制會導(dǎo)致執(zhí)行效率過低。其實在復(fù)制過程中,子進程復(fù)制了父進程的task_struct,系統(tǒng)堆棧空間和頁面表,這意味著上面的程序,我們沒有執(zhí)行count++前,其實子進程和父進程的count指向的是同一塊內(nèi)存。而當子進程改變了父進程的變量時候,會通過copy_on_write的手段為所涉及的頁面建立一個新的副本。所以當我們執(zhí)行++count后,這時候子進程才新建了一個頁面復(fù)制原來頁面的內(nèi)容,基本資源的復(fù)制是必須的,而且是高效的。整體看上去就像是父進程的獨立存儲空間也復(fù)制了一遍。
?
在fork中,父子進程是獨立開來的 ,并沒有影響
?
2.vfork函數(shù)
vfork創(chuàng)建出來的不是真正意義上的進程,而是一個線程,因為它缺少了上面提到的進程的四要素的第4項,獨立的內(nèi)存資源,我們編一個程序練習(xí):
[cpp]?view plaincopy
?
然后編譯,執(zhí)行,得到下列結(jié)果:
Before create son, the father's count is:1
This is son, his pid is: 4048 and the count is: 2
After son, This is father, his pid is:?4048 and the count is: 2, and the child is: 2748
從這里我們看到,子進程和父進程是共享count的,也就是說,內(nèi)存區(qū)是共享的
另外由vfork創(chuàng)造出來的子進程還會導(dǎo)致父進程掛起,除非子進程exit或者execve才會喚起父進程,看下面程序:
[cpp]?view plaincopy
好,編譯通過,執(zhí)行。。。
Before create son, the father's count is:1
This is son, The i is: 0
...
...
This is son, The i is: 68
This is son, The i is: 69
This is son, The i is: 70
After son, This is father, his pid is:?2564 and the count is: 1, and the child is: 2736
?
可以看到父進程總是等子進程執(zhí)行完畢后才開始繼續(xù)執(zhí)行
總結(jié)
以上是生活随笔為你收集整理的进程控制1--fork vfork函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 拨打120表述不清怎么办?专家解读:注意
- 下一篇: Intel处理器明年又要换LGA1851