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