Linux中的fork函數


操作系統實驗二

fork函數

作用

fork函數將運行着的程序分成2個(幾乎)完全一樣的進程,每個進程都啟動一個從代碼的同一位置開始執行的線程

返回值

  • 負值:創建子進程失敗。
  • 零:返回到新創建的子進程。
  • 正值:返回父進程或調用者。該值包含新創建的子進程的進程ID
    image

用法

pid_t pid=fork();如果創建成功,會有兩個進程:父進程和子進程,fork在這兩個進程中分別返回,就是返回兩次且返回值不同。

一段程序

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

int main()
{ 
  int pid1, pid2;
  printf("I am father %d! My father is %d.\n", getpid(), getppid());
  if ((pid1 = fork())<0) //fork return value < 0 , create failed
  {
    printf("Child1 fail create!\n");
    return 1;
  }
  else if (pid1 == 0)  //fork return value = 0, son is running
  {
    printf("I am son %d! My father is %d. \n", getpid(), getppid());
    return 0;
  }
  if ((pid2 = fork())<0)
  {
    printf("Child2 fail create!\n");
    return 0;
  }
  else if (pid2 == 0)
  {
    printf("I am daughter %d! My father is %d.\n", getpid(), getppid());
    return 0;
  }
}

編譯運行

gcc fork.c -o fork
./fork

運行結果
image
分析: 首先是父進程,打印了它的身份和進程號,還有它的父進程號
在第一個if語句中創建了子進程,子進程創建成功,返回值是0,執行第一個else if,打印身份是子進程和它的進程號和父進程號。
父進程的fork返回值是子進程號大於0,不滿足第一個條件,順序往下執行,在第二個if里創建了一個進程。
子進程創建成功,返回值是0,執行else if,打印身份、進程號和父進程號。
daughter進程的父進程號時884,是因為父進程已經運行結束了,daughter進程找不到原來的父進程,變成了孤兒進程,被其他進程收養了。
image
分析: 有時daughter進程和son進程順序不一樣是因為父進程比son進程執行的快,先創建了daughter進程,daughter進程先進行了打印。
打印在命令行上的原因:
處理父進程、son進程、daughter進程,還有一個shell進程,shell進程就是用戶和linux交互的進程,用於解析輸入的命令行。這四個進程都要搶占屏幕這個資源,如果被shell先搶占了,就會出現命令行,其他進程輸出就會在命令行上了。(不知道理解的對不對。。。)

孤兒進程

父進程運行結束后,它創建的子進程還在運行,這些子進程就會成為孤兒進程。
避免出現孤兒進程: 在父進程運行最后加上sleep(1),父進程不會運行那么快,保證子進程先退出。
image

lockf函數

參考:https://blog.csdn.net/qq_24421591/article/details/49104455

用處

實現資源的互斥訪問

例子

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

int main(){
    int pid1, pid2;
    pid1=fork();
    if(pid1 == 0)
    {
        for(int i = 0; i < 5; i ++ )
        {
            lockf(1,1,0); 	//加鎖
            printf("I am son %d\n",i);
            lockf(1,0,0); //解鎖
            sleep(3); //等待3s
        }
    }
    else
    {
        pid2=fork();
        if(pid2 == 0)
        {
            for(int i = 0; i < 5; i ++ )
            {
                lockf(1,1,0);
                printf("I am daughter %d\n",i);
                lockf(1,0,0);
                sleep(3);
            }
        }
        else
        {
            printf("I am father\n");
        }
    }
	return 0;
}

image
分析: 臨界資源是屏幕,son進程和daughter進程會交替打印,是因為在循環中打印過后,會等待3s,在等待的時間里,另一個進程就是搶占資源,進行打印。
對比
將sleep(1)放在解鎖之前,這樣即使進程在sleep,其他進程也沒有機會搶占資源。
image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM