1. 程式人生 > >fork後父子程序共享資源

fork後父子程序共享資源

fork後父子程序共享資源

Unix環境高階程式設計中8.3節中說,“子程序是父程序的副本。例如,子程序獲得父程序資料空間、堆和棧的副本。注意,這是子程序所擁有的副本。父程序和子程序並不共享這些儲存空間部分。父程序和子程序共享正文段。”

書中還預留了例子說明子程序對變數所做的改變並不影響父程序中該變數的值。

/**
 * fork.c
 * 探討父子程序共享變數問題
 **/

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

int globvar = 6;        /* external variable in initialized data */
char buf[] = "a write to stdout\n";

int 
main(void)
{
    int var;    /* automatic variable on the stach */
    pid_t pid;

    var = 88;
    if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1)
    {
        perror("write error");
        exit(1);
    }
    printf("before fork\n");    /* we don't flush stdout */

    if ((pid = fork()) < 0)
    {
        perror("fork error");
        exit(1);
    } else if (pid == 0) {    /* child */
        globvar++;          /* modify variables */
        var++;
    } else {
        sleep(2);           /* parent */
    }

    printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar, var);
    exit(0);
}

編譯和執行程式,如下:

/myblog/source/fork# gcc fork.c -o fork
/myblog/source/fork# ./fork
a write to stdout
before fork
pid = 12071, glob = 7, var = 89
pid = 12070, glob = 6, var = 88

如上,可以看出,fork後子程序只是獲得了父程序的副本,所有變數的變更都只在各自程序中有效。

實際上,fork後子程序和父程序共享的資源還包括:

  • 開啟的檔案
  • 實際使用者ID、實際組ID、有效使用者ID、有效組ID
  • 新增組ID
  • 程序組ID
  • 會話期ID
  • 控制終端
  • 設定-使用者-ID標誌和設定-組-ID標誌
  • 當前工作目錄
  • 根目錄
  • 檔案方式建立遮蔽字
  • 訊號遮蔽和排列
  • 對任一開啟檔案描述符的在執行時關閉標誌
  • 環境
  • 連線的共享儲存段(共享記憶體)
  • 資源限制

父子程序之間的區別是:

  • fork的返回值
  • 程序ID
  • 不同的父程序ID
  • 子程序的tms_utime,tms_stime,tms-cutime以及tms_ustime設定為0
  • 父程序設定的鎖,子程序不繼承
  • 子程序的未決告警被清除
  • 子程序的未決訊號集設定為空集

參考文獻

[1] Unix環境高階程式設計(第3版)

[2] http://blog.csdn.net/u012138828/article/details/39031823