iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0
Software Development

十年後重讀作業系統恐龍本系列 第 4

ch3圖3.9-使用UNIX fork()系統呼叫產生獨立行程

  • 分享至 

  • xImage
  •  

例子:父行程等它的子行程中止後才繼續執行

名詞定義:

  • 行程(process):執行中的程式。
  • 父(parent)行程:產生它的行程。
  • 子(chid)行程:它產生的任何行程。
  • 兄弟(sibling)行程:有相同父行程的子行程。
  • 行程識別碼(pid, process identifier):為系統每一個行程提供一個獨一無二的數字,通常是整數,可作為索引值來存取核心內行程的各種屬性。

當一個行程產生一個新的行程時,在執行作法上有兩種:

  1. 父行程繼續執行而子行程也同時執行。
  2. 父行程等著它的所有子行程中止後才繼續執行。

以下程式介紹第2種,父行程等著它的所有子行程中止後才繼續執行:

newproc-posix.c

/**
 * This program forks a separate process using the fork()/exec() system calls.
 *
 * Figure 3.09
 *
 * @author Silberschatz, Galvin, and Gagne
 * Operating System Concepts  - Ninth Edition
 * Copyright John Wiley & Sons - 2013
 */

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

int main()
{
pid_t pid;

	/* fork a child process */
	pid = fork();

	if (pid < 0) { /* error occurred */
		fprintf(stderr, "Fork Failed\n");
		return 1;
	}
	else if (pid == 0) { /* child process */
		printf("I am the child %d\n",pid);
		execlp("/bin/ls","ls",NULL);
	}
	else { /* parent process */
		/* parent will wait for the child to complete */
		printf("I am the parent %d\n",pid);
		wait(NULL);
		
		printf("Child Complete\n");
	}
    
    return 0;
}

Terminal
編譯並執行

gcc -o newproc-posix newproc-posix.c 
./newproc-posix

結果:
https://ithelp.ithome.com.tw/upload/images/20240918/20168766GbHLsRKRBW.png

我的解釋:

  1. 首先 fork() 產生子行程。
pid = fork();
  1. 會先繼續做父行程,印出 I am the parent 3272 後等待子行程完成(3272 會變動)。
else { /* parent process */
		/* parent will wait for the child to complete */
		printf("I am the parent %d\n",pid);
		wait(NULL);
  1. 進來子行程印出 I am the child 0,子行程的 pid 固定為 0。

接著說明看不懂的 execlp 這行:

  • execlp 函數說明:在 Unix/Linux 系統中用來執行程序的函數,屬於 exec 系列函數之一。它會用指定的程序替換當前行程的映像,這意味著當 execlp 成功執行後,原本的行程內容將不再存在。
  • "/bin/ls" 參數說明:這是要執行的程序的路徑。在這裡,/bin/ls 是一個列出當前目錄文件的命令。
  • "ls" 參數說明:傳遞給新程序的第一個參數,通常是程序的名稱。在許多情況下,這個參數會用於顯示在行程列表中。
  • NULL 參數說明:這表示參數列表的結束。在 execlp 中,必須以 NULL 結束參數列表,以告訴函數何時停止讀取參數。
    上圖結果中可驗證,此行與 ls 結果一樣,印出此文件夾所有檔名。
else if (pid == 0) { /* child process */
		printf("I am the child %d\n",pid);
		execlp("/bin/ls","ls",NULL); /* 同 ls */
	}
  1. 子行程執行完成,回到父行程,印出 Child Complete ,return 0 結束程式。
		printf("Child Complete\n");
	}

https://ithelp.ithome.com.tw/upload/images/20240918/20168766bg93qiiMBh.jpg

參考:greggagne/OSC9e/ch3/newproc-posix.c


上一篇
ch3圖3.30-Line A 將輸出什麼?
下一篇
ch3圖3.17,18-說明POSIX共用記憶體API的行程
系列文
十年後重讀作業系統恐龍本30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言