生活随笔
收集整理的這篇文章主要介紹了
进程控制1--fork vfork函数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
linux系統調用fork()創建一個和當前進程完全相同的拷貝進程,其中父進程和子進程的代碼段,堆棧段,數據段均獨立
?
進程必須的4要點:
a.要有一段程序供該進程運行
b.進程專用的系統堆棧空間。
c.進程控制塊,在linux中具體實現是task_struct
d.有獨立的存儲空間。
當一個進程缺少其中一個條件時候,我們稱其為線程。
?
1.先看fork()的原型 :
?
#include<sys/types.h> /* 提供類型pid_t的定義 */ #include<unistd.h> /* 提供函數的定義 */ pid_t fork(void); 返回: 父進程中執行則返回子進程PID,子進程中執行返回0
?
現在進行一個例子,創建一個子進程,然后根據返回的 PID進行識別:
[cpp] ?view plaincopy
?? #include?<sys/types.h> ?? #include?<sys/stat.h> ?? #include?<unistd.h> ?? ?? main()?? {?? ????????int ?count?=?0;?? ????pid_t?pid;???????????? ????pid=fork();????? ????if (pid<0)???? ?????? ????printf("error?in?fork!" );????? ????else ??? ????{?? ????if (pid==0)?????? ?? ????????printf("I?am?the?child?process,?my?count?is?%d,my?process?ID?is?%d/n" ,count,getpid());?? ????else ???????? ?? ????????printf("I?am?the?parent?process,my?count?is?%d,?my?process?ID?is?%d/n" ,++count,getpid());?? ????}?? }??
弄好后,在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不同,內存資源count是值得復制,父進程改變了count的值,而子進程中的count沒有被改變。有人認為這樣大批量的復制會導致執行效率過低。其實在復制過程中,子進程復制了父進程的task_struct,系統堆??臻g和頁面表,這意味著上面的程序,我們沒有執行count++前,其實子進程和父進程的count指向的是同一塊內存。而當子進程改變了父進程的變量時候,會通過copy_on_write的手段為所涉及的頁面建立一個新的副本。所以當我們執行++count后,這時候子進程才新建了一個頁面復制原來頁面的內容,基本資源的復制是必須的,而且是高效的。整體看上去就像是父進程的獨立存儲空間也復制了一遍。
?
在fork中,父子進程是獨立開來的 ,并沒有影響
?
2.vfork函數
vfork創建出來的不是真正意義上的進程,而是一個線程,因為它缺少了上面提到的進程的四要素的第4項,獨立的內存資源,我們編一個程序練習:
[cpp] ?view plaincopy
#include?<sys/types.h> ?? #include?<sys/stat.h> ?? #include?<unistd.h> ?? ?? main()??? {?? ????????int ?count?=?1;?? ????????int ?child;?? ?? ????????printf("Before?create?son,?the?father's?count?is:%d/n" ,?count); ?? ????????if (!(child?=?vfork()))? ?? ????{?? ????????????????printf("This?is?son,?his?pid?is:?%d?and?the?count?is:?%d/n" ,?getpid(),?++count);?? ????????????????exit(1);?? ????????}?else ??? ????{?? ????????????????printf("After?son,?This?is?father,?his?pid?is:?%d?and?the?count?is:?%d,?and?the?child?is:?%d/n" ,?????? ?? ????getpid(),?count,?child);?? ????????}?? }??
?
然后編譯,執行,得到下列結果:
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的,也就是說,內存區是共享的
另外由vfork創造出來的子進程還會導致父進程掛起,除非子進程exit或者execve才會喚起父進程,看下面程序:
[cpp] ?view plaincopy
#include?<sys/types.h> ?? #include?<sys/stat.h> ?? #include?<unistd.h> ?? ?? main()??? {?? ????????int ?count?=?1;?? ????????int ?child;?? ?? ????????printf("Before?create?son,?the?father's?count?is:%d/n" ,?count);?? ????????if (!(child?=?vfork()))?? ?????{?? ????????????????int ?i;?? ????????????????for (i?=?0;?i?<?100;?i++)??? ????????{?? ????????????????????????printf("This?is?son,?The?i?is:?%d/n" ,?i);?? ????????????????????????if (i?==?70)?? ????????????????????????????????exit(1);?? ????????????????}?? ????????????????printf("This?is?son,?his?pid?is:?%d?and?the?count?is:?%d/n" ,?getpid(),?++count);?? ????????????????exit(1);?? ????????}??? ????else ?? ?????{?? ????????????????printf("After?son,?This?is?father,?his?pid?is:?%d?and?the?count?is:?%d,?and?the?child?is:?%d/n" ,?????? ?? ????getpid(),?count,?child);?? ????????}?? }??
好,編譯通過,執行。。。
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
?
可以看到父進程總是等子進程執行完畢后才開始繼續執行
總結
以上是生活随笔 為你收集整理的进程控制1--fork vfork函数 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。