<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Linux進程Fork詳解

      一. fork函數詳解

      一個進程,包括代碼、數據和分配給進程的資源。fork()函數通過系統調用創建一個與原來進程幾乎完全相同的進程,也就是兩個進程可以做完全相同的事,但如果初始參數或者傳入的變量不同,兩個進程也可以做不同的事。

      一個進程調用fork()函數后,系統先給新的進程分配資源,例如存儲數據和代碼的空間。然后把原來的進程的所有值都復制到新的新進程中,只有少數值與原來的進程的值不同。相當于克隆了一個自己。

      我們來看一個例子:

      #include <unistd.h>
      #include <stdio.h>
      
      int main() {
          pid_t fpid; //fpid表示fork函數返回的值
          int count = 0;
          fpid = fork();
          if (fpid < 0)
              printf("error in fork!");
          else if (fpid == 0) {
              printf("i am the child process, my process id is %d\n", getpid());
              count++;
          } else {
              printf("i am the parent process, my process id is %d\n", getpid());
              count++;
          }
          printf("統計結果是: %d\n", count);
          return 0;
      }
      

      運行結果是:

      在語句fpid=fork()之前,只有一個進程在執行這段代碼,但在這條語句之后,就變成兩個進程在執行了,這兩個進程的幾乎完全相同,將要執行的下一條語句都是if(fpid<0)……

      為什么兩個進程的fpid不同呢,這與fork函數的特性有關。fork調用的一個奇妙之處就是它僅僅被調用一次,卻能夠返回兩次,它可能有三種不同的返回值:

      1. 在父進程中,fork返回新創建子進程的進程ID;
      2. 在子進程中,fork返回0;
      3. 如果出現錯誤,fork返回一個負值;

      在fork函數執行完畢后,如果創建新進程成功,則出現兩個進程,一個是子進程,一個是父進程。在子進程中,fork函數返回0,在父進程中,fork返回新創建子進程的進程ID。我們可以通過fork返回的值來判斷當前進程是子進程還是父進程。

      fork出錯可能有兩種原因:

      1. 當前的進程數已經達到了系統規定的上限,這時errno的值被設置為EAGAIN。
      2. 系統內存不足,這時errno的值被設置為ENOMEM。

      創建新進程成功后,系統中出現兩個基本完全相同的進程,這兩個進程執行沒有固定的先后順序,哪個進程先執行要看系統的進程調度策略。

      每個進程都有一個獨特(互不相同)的進程標識符(process ID),可以通過getpid()函數獲得,還有一個記錄父進程pid的變量,可以通過getppid()函數獲得變量的值。

      fork執行完畢后,出現兩個進程:

      有人說兩個進程的內容完全一樣啊,怎么打印的結果不一樣啊,那是因為判斷條件的原因,上面列舉的只是進程的代碼和指令,還有變量啊。
      執行完fork后,進程1的變量為count=0,fpid!=0(父進程)。進程2的變量為count=0,fpid=0(子進程),這兩個進程的變量都是獨立的,存在不同的地址中,不是共用的,這點要注意。可以說,我們就是通過fpid來識別和操作父子進程的。

      還有人可能疑惑為什么不是從#include處開始復制代碼的,這是因為fork是把進程當前的情況拷貝一份,執行fork時,進程已經執行完了int count=0;fork只拷貝下一個要執行的代碼到新的進程。

      需要注意的是,在fork之后兩個進程用的是相同的物理空間(內存區),子進程的代碼段、數據段、堆棧都是指向父進程的物理空間,也就是說,兩者的虛擬空間不同,其對應的物理空間是一個。這是出于效率的考慮,在Linux中被稱為“寫時復制”(COW)技術,只有當父子進程中有更改相應段的行為發生時,再為子進程相應的段分配物理空間。另外fork之后內核會將子進程排在隊列的前面,以讓子進程先執行,以免父進程執行導致寫時復制,而后子進程執行exec系統調用,因無意義的復制而造成效率的下降。

      二. 代碼分析

      先看一份代碼:

      #include <unistd.h>
      #include <stdio.h>
      
      int main() {
          pid_t cld_pid;
          int a = 1, b = 2;
          for (int i = 0; i < 2; i++) {
              if ((cld_pid = fork()) == 0) {
                  a += 1;
                  printf("a=%d  b=%d\n", a, b);
              } else {
                  b += 1;
                  printf("a=%d  b=%d\n", a, b);
              }
          }
          return 0;
      }
      

      代碼結果:

      執行流程:

      圖中實線箭頭代表進程內變量的變化過程,虛線箭頭代表進程之間的fork操作,產生子進程。

      本文參考至:

      【Linux 進程】fork函數詳解 - 我得去圖書館了 - 博客園 (cnblogs.com)

      神奇的fork(父子進程中一些神奇的問題) - 簡書 (jianshu.com)

      posted @ 2021-10-24 11:36  聽到微笑  閱讀(36)  評論(0)    收藏  舉報  來源
      主站蜘蛛池模板: 亚洲老熟女一区二区三区| 人妻中文字幕一区二区三| 亚洲精品天堂在线观看| 熟女人妻精品一区二区视频| 日本高清色WWW在线安全| 老司机精品影院一区二区三区| 99热精品毛片全部国产无缓冲| 人妻丝袜无码专区视频网站| 无码国内精品久久人妻蜜桃| 中文字幕日韩有码国产| 国产成人高清亚洲一区二区| 一二三四日本高清社区5| 麻豆精品一区二区三区蜜臀| 狠狠躁夜夜躁人人爽天天5| 粉嫩小泬无遮挡久久久久久| 亚洲人成网站77777在线观看| 九九热精彩视频在线免费| 小污女小欲女导航| 国产又色又爽又黄的视频在线| 日韩av中文字幕有码| 在线免费播放av观看| 亚洲午夜性猛春交XXXX | 性欧美vr高清极品| 99久久er这里只有精品18| 国产精品国产精品国产专区| 国产不卡一区二区三区视频| 国产在线精品一区二区夜色| 精品国产AV最大网站| 亚洲三区在线观看无套内射 | 日本黄页网站免费大全| 无码伊人66久久大杳蕉网站谷歌| 国产精品制服丝袜第一页| 亚洲另类无码一区二区三区| 无码一区二区三区久久精品| 亚洲欧美偷国产日韩| 国产一区| 日韩免费无码一区二区三区| 无码国产精品成人| av一区二区中文字幕| 精品国产成人午夜福利| 在线免费播放av观看|