日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

进程控制1--fork vfork函数

發布時間:2023/12/10 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 进程控制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
  • /*test.c*/??
  • #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函数的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。