国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Linux:創(chuàng)建進(jìn)程 -- fork,到底是什么?

這篇具有很好參考價(jià)值的文章主要介紹了Linux:創(chuàng)建進(jìn)程 -- fork,到底是什么?。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

?相信大家在初學(xué)進(jìn)程時(shí),對(duì)fork函數(shù)創(chuàng)建進(jìn)程一定會(huì)有很多的困惑,比如:

  • 1.fork做了什么事情???
  • 2.為什么fork函數(shù)會(huì)有兩個(gè)返回值?
  • 3.為什么fork的兩個(gè)返回值,會(huì)給父進(jìn)程諒回子進(jìn)程pid,給子進(jìn)程返回0?
  • 4.fork之后:父子進(jìn)程誰(shuí)先運(yùn)行??
  • 5.如何理解同一個(gè)變量,會(huì)有不同的值??

本篇文章將來(lái)仔細(xì)回答一下這些問(wèn)題。

目錄

1.如何查看進(jìn)程

2. 通過(guò)系統(tǒng)調(diào)用創(chuàng)建進(jìn)程-fork

2.1 初識(shí)fork

2.2 fork原理


1.如何查看進(jìn)程

1.1 進(jìn)程的信息可以通過(guò) /proc 系統(tǒng)文件夾查看

通過(guò)ls指令來(lái)查看所有的進(jìn)程,proc是動(dòng)態(tài)目錄結(jié)構(gòu),用來(lái)存放所有的進(jìn)程,目錄的名稱就是用進(jìn)程的id命名的。

Linux:創(chuàng)建進(jìn)程 -- fork,到底是什么?,Linux,linux,進(jìn)程,fork

1.2 進(jìn)程信息同樣可以使用ps(process status)工具來(lái)獲取

  • 進(jìn)程id(PID)通過(guò)getpid 系統(tǒng)調(diào)用獲得
  • 父進(jìn)程id(PPID)通過(guò)getppid 系統(tǒng)調(diào)用獲得
   #include<stdio.h>
   #include<sys/types.h>
   #include<unistd.h>
   int main()
   {
      while(1)
      {
          printf("I am a process! myid:%d parentid:%d\n",getpid(),getppid())    ;
          sleep(1);
      }
      return 0;
  }

?我們可以使用shell再開一個(gè)窗口登錄一次進(jìn)行查看。

Linux:創(chuàng)建進(jìn)程 -- fork,到底是什么?,Linux,linux,進(jìn)程,fork

"aux" 是 "ps" 命令的選項(xiàng)之一,表示顯示所有用戶的所有進(jìn)程,通過(guò)查詢,可以看到你自己 ./ 啟動(dòng)的進(jìn)程,最后一個(gè)進(jìn)程是當(dāng)前的grep的查找進(jìn)程。

關(guān)于當(dāng)前工作目錄

我們?cè)贑語(yǔ)言學(xué)習(xí)文件操作是會(huì)提到當(dāng)前目錄,我們以 "w" 方式讀取文件時(shí),如果文件不存在,那么文件會(huì)在當(dāng)前工作目錄cwd下創(chuàng)建。那么一個(gè)進(jìn)程是如何找到當(dāng)前目錄的呢?

我們讓下面代碼運(yùn)行起來(lái)

  1 #include<stdio.h>
  2 #include<sys/types.h>
  3 #include<unistd.h>
  4 int main()
  5 {
  6     //更改當(dāng)前工作目錄
  7     chdir("./wdz");//沒有這個(gè)目錄不會(huì)更改,我這里是創(chuàng)建好了這個(gè)目錄                                                       
  8 
  9     // cwd/hello.txt  
 10     FILE* file = fopen("hello.txt","w");//文件不存在會(huì)在當(dāng)前工作目錄下創(chuàng)建
 11     if(file==NULL)
 12     {
 13         return 1;
 14     }
 15     fclose(file);
 16 
 17 
 18     while(1)
 19     {
 20         printf("I am a process! myid:%d parentid:%d\n",getpid(),getppid());
 21         sleep(1);
 22     }
 23     return 0;
 24 }

Linux:創(chuàng)建進(jìn)程 -- fork,到底是什么?,Linux,linux,進(jìn)程,fork

??這里通過(guò)修改當(dāng)前目錄已經(jīng)對(duì)將文件創(chuàng)建在更改的目錄下:

Linux:創(chuàng)建進(jìn)程 -- fork,到底是什么?,Linux,linux,進(jìn)程,fork??可以發(fā)現(xiàn):

  • 默認(rèn)情況下,進(jìn)程所處的目錄就是當(dāng)前工作目錄?
  • 一個(gè)進(jìn)程可以找到自己的可執(zhí)行程序
  • 每一個(gè)進(jìn)程都有自己的工作目錄

2. 通過(guò)系統(tǒng)調(diào)用創(chuàng)建進(jìn)程-fork

2.1 初識(shí)fork

首先使用fork創(chuàng)建一個(gè)進(jìn)程?

    #include<stdio.h>
    #include<unistd.h>
    #include<sys/types.h>
   
   int main()
   {
       printf("我是一個(gè)父進(jìn)程我的pid:%d\n",getpid());
      
      //創(chuàng)建一個(gè)子進(jìn)程! 
      pid_t id = fork();
      
    //fork之前只有父進(jìn)程會(huì)執(zhí)行fork之前的代碼,fork之后父子進(jìn)程都要執(zhí)行后面的代碼
  
      while(1)
      {
          printf("我是一個(gè)進(jìn)程,pid:%d,ppid%d,fork return:%d\n",getpid(),getppid(),id);
            //這個(gè)printf函數(shù)在代碼這里只調(diào)用一次,但在運(yùn)行時(shí)調(diào)用了兩次
          sleep(1);//for test
      }
      return 0;
  }

?運(yùn)行結(jié)果:

Linux:創(chuàng)建進(jìn)程 -- fork,到底是什么?,Linux,linux,進(jìn)程,fork

看到這里大家的疑惑就出來(lái)了

目前可以發(fā)現(xiàn):只有父進(jìn)程執(zhí)行fork之前的代碼,fork之后,父子進(jìn)程都要執(zhí)行后續(xù)的代碼!

一個(gè)函數(shù)竟然會(huì)有兩個(gè)返回值???fork成功的時(shí)候,會(huì)有兩個(gè)不同的返回值,給子進(jìn)程返回0;
給父進(jìn)程返回子進(jìn)程的pid

fork代碼的一般寫法:

1.我們?yōu)槭裁匆獎(jiǎng)?chuàng)建子進(jìn)程?

????????我們想讓子進(jìn)程協(xié)作父進(jìn)程完成一些工作,這些工作是單進(jìn)程解決不了的

2.我們創(chuàng)建子進(jìn)程是為了讓子進(jìn)程和父進(jìn)程做一樣的事情嗎??

????????我們創(chuàng)建子進(jìn)程,就是為了讓子進(jìn)程和父進(jìn)程做不一樣的事情,執(zhí)行不一樣的代碼

3. 應(yīng)該如何保證父子進(jìn)程做不一樣的事情呢?

????????可以通過(guò)判斷fork的返回值,判斷誰(shuí)是父,誰(shuí)是子,然后讓他們執(zhí)行不同的代碼片段!!

使用 if 對(duì)父子進(jìn)程分流:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>

int main()
{
    printf("我是一個(gè)父進(jìn)程我的pid:%d\n",getpid());
    
    //創(chuàng)建一個(gè)子進(jìn)程! 
    //bash也是用C語(yǔ)言寫的,命令行啟動(dòng)的進(jìn)程,都是bash的子進(jìn)程,所以bash源代碼中創(chuàng)建子進(jìn)程也是用的fork
    pid_t id = fork();  
    
    //fork()之后,用if進(jìn)行分流    
    if(id<0) return 1; //進(jìn)程創(chuàng)建失敗                                                                                                          
    else if(id == 0)      
    {                  
        //子進(jìn)程       
        while(1)       
        {              
            printf("我是子進(jìn)程,pid:%d,ppid%d,ret:%d,正在執(zhí)行下載\n",getpid(),getppid(),id); 
            sleep(1);//for test      
        }              
    }                  
    else               
    {                  
        //父進(jìn)程       
        while(1)       
        {              
            printf("我是父進(jìn)程,pid:%d,ppid%d,ret:%d,正在執(zhí)行播放任務(wù)\n",getpid(),getppid(),id);   
            sleep(1);//for test    
        }
    }

    return 0;
}

執(zhí)行結(jié)果

Linux:創(chuàng)建進(jìn)程 -- fork,到底是什么?,Linux,linux,進(jìn)程,fork

可以發(fā)現(xiàn)通過(guò) if 對(duì)fork函數(shù)返回值進(jìn)行判斷,實(shí)現(xiàn)了父子進(jìn)程可以執(zhí)行不同的任務(wù)。

2.2 fork原理

對(duì)于上面的現(xiàn)象,我們來(lái)解答一下疑惑

  • 1.fork做了什么事情???
  • 2.為什么fork函數(shù)會(huì)有兩個(gè)返回值?
  • 3.為什么fork的兩個(gè)返回值,會(huì)給父進(jìn)程諒回子進(jìn)程pid,給子進(jìn)程返回0?
  • 4.fork之后:父子進(jìn)程誰(shuí)先運(yùn)行??
  • 5.如何理解同一個(gè)變量,會(huì)有不同的值??

1. fork做了什么事情???

? ? ? ?用于創(chuàng)建一個(gè)進(jìn)程,在內(nèi)核中操作系統(tǒng)重新為其申請(qǐng)了一個(gè)PCB,并使用父進(jìn)程的PCB進(jìn)行初始化,且子進(jìn)程與父進(jìn)程同時(shí)指向相同的代碼。所以fork之前的代碼子進(jìn)程也是可以看到的。

那為什么子進(jìn)程不從頭開始執(zhí)行呢?

????????因?yàn)橛谐绦蛴?jì)數(shù)器pc,會(huì)使代碼一句一句執(zhí)行,子進(jìn)程在創(chuàng)建時(shí)和繼承父進(jìn)程的pc。所以說(shuō)也會(huì)繼續(xù)向下執(zhí)行。


2.為什么fork函數(shù)會(huì)有兩個(gè)返回值??

????????首先f(wàn)ork是一個(gè)函數(shù),如果一個(gè)函數(shù)return時(shí),說(shuō)明一個(gè)函數(shù)的核心工作已經(jīng)做完。我們知道fork之后代碼會(huì)共享,所以是fork函數(shù)做完核心工作后就會(huì)共享,return也會(huì)父子進(jìn)程共享,所以會(huì)有兩個(gè)返回值。


3.為什么fork的兩個(gè)返回值,會(huì)給父進(jìn)程諒回子進(jìn)程pid,給子進(jìn)程返回0?

????????因?yàn)橐粋€(gè)父進(jìn)程可以有多個(gè)子進(jìn)程,父進(jìn)程信息中只有pid 和 ppid,為了唯一確定子進(jìn)程,以后管理和控制子進(jìn)程,所以返回子進(jìn)程的pid,而子進(jìn)程中由于有父進(jìn)程ppid,所以返回0用來(lái)判斷進(jìn)程創(chuàng)建成功沒有即可。


4.fork之后:父子進(jìn)程誰(shuí)先運(yùn)行??

????????不確定。創(chuàng)建完成子進(jìn)程,只是一個(gè)開始。創(chuàng)建完成子進(jìn)程之后,系統(tǒng)的其他進(jìn)程,父進(jìn)程,和子進(jìn)程,接下來(lái)要被調(diào)度執(zhí)行的,當(dāng)父子進(jìn)程的PCB都被創(chuàng)建并在運(yùn)行隊(duì)列中排隊(duì)的時(shí)候,哪一個(gè)進(jìn)程的PCB先被選擇調(diào)度,那個(gè)進(jìn)程就先運(yùn)行,由操作系統(tǒng)自主決定??!由各自PCB中的調(diào)度信息(時(shí)間片,優(yōu)先級(jí)等)+調(diào)度器算法共同決定。


?5.如何理解同一個(gè)變量,會(huì)有不同的值??

????????進(jìn)程的獨(dú)立性,首先是表現(xiàn)在有各自的PCB,進(jìn)行之間不會(huì)互相影響!代碼本身是只讀的,不會(huì)影響!但是數(shù)據(jù)父子是會(huì)修改的,所以代碼共享,但是數(shù)據(jù)各個(gè)進(jìn)程必須想辦法各自私有一份??!

這個(gè)怎么做到的?通過(guò)寫時(shí)拷貝。這樣做的好處就是不用將所有的數(shù)據(jù)都進(jìn)行拷貝,當(dāng)數(shù)據(jù)需要修改時(shí)才做拷貝,可以提高效率。

本篇結(jié)束!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-753382.html

到了這里,關(guān)于Linux:創(chuàng)建進(jìn)程 -- fork,到底是什么?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包