2014/03/16

[Linux] fork()的使用介紹

整個作業系統(Operating System, OS)是為了分配有限的硬體資源給Program使用,然而OS也視為一個Program,放進CPU中執行,為了讓OS Kernel辨識每個Process,就會有所謂的行程辨識元(Process Identifier, PID),其中特別的是PID 0和1,0是Kernel用來Swap,交換分頁使用;而1則是初始化行程,也是Kernel建立的第一個Process,其他的Process基本上都是透過PID 1的init Process來產生。因此整個OS系統本身可以想像成一個Tree of Processes,root為init Process,亦為Parent Process,然後用fork()依序產生底下的Child Process,並回傳值0代表是Child Process。

系統函數fork()是用來產生process,讓OS可以達到multitasking或multithreading的功能,底下為兩個使用fork()函數的範例,一個是由Parent Process創建一個Child Process,然後Parent Process會等待Child Process執行完工作後,才繼續執行。另外一個則是,既然是兩個Process,Process之間就會有資料傳遞的問題,communication可以透過Sockets, Remote Procedure Calls和Pipes來傳遞。而此範例是採用Pipes的方式來傳遞,由Child Process傳遞字串”Greetings”給Parent Process讀取。

fork_example.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
 pid_t pid;
 /*fork another porcess*/
 pid = fork();
 if(pid<0) /*error occurred*/
 {
  fprintf(stderr, "Fork Failed");
  exit(-1);
 }
 else if(pid==0) /*child process*/
 {
  execlp("/bin/ls","ls",NULL);
 }
 else /*parent process*/
 {
  wait(NULL);
  printf("Child Complete\n");
  exit(0);
 }
}


執行結果

ordinary_pipe.c
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define BUFFER_SIZE 25
#define READ_END 0
#define WRITE_END 1

int main(void)
{
 char write_msg[BUFFER_SIZE] = "Greetings";
 char read_msg[BUFFER_SIZE];
 int fd[2];
 pid_t pid;
 
 if(pipe(fd)==-1)
 {
  fprintf(stderr,"Pipe failed");
  return 1; 
 } 
 
 pid = fork();
 
 if(pid<0)
 {
  fprintf(stderr, "Fork Failed");
  return 1;
 }
 
 if(pid>0)
 {
  close(fd[READ_END]);
  write(fd[WRITE_END], write_msg, strlen(write_msg)+1);
  close(fd[WRITE_END]); 
 } else
 {
  close(fd[WRITE_END]);
  read(fd[READ_END], read_msg, BUFFER_SIZE);
  printf("\nread %s\n", read_msg);
  close(fd[READ_END]);
 }
 
 return 0;
 
}


執行結果

沒有留言:

張貼留言