image

qke 奇客

有意思的fork

有意思的fork
pid_t fork(void)函数用来创建新的进程。
相关函数有wait exec等。
该函数创建一次,返回两次。
可以根据返回值区别当前进程是父进程,还是新创建的子进程。
子进程中返回值为0,父进程中返回其子进程号,出错为-1.

在fork()这个地方,新加了一个执行入口。子进程
拷贝了父进程的所有数据,堆栈空间,并继承了父进程的用户代码、组代码、环境变量、已经打开的
文件代码、工作目录和资源限制。子进程从父进程继承下列属性:
实际用户号、有效用户号以及保留的用户号
实际组号、有效组号以及保留的组号
补充组号列表
环境
文件描述符
执行时关闭标识
信号处理设置
信号掩码
配置处理开|关状态
记录帐号中的命令名
Nice值
所有连接的共享内存段
当前工作目录
根目录
文件模式创建掩码
文件大小限制
实时优先级
因为是数据的备份,所以这些数据并不能相互影响。
下面看一个例子:(是从Linux 高级程序与设计 人民邮电出版社 P151变形而来,原书中给出的结果有错误)

  1. //getpgid_example.c
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. int main(int argc ,char** agrv)
  6. {
  7.         int i;
  8.         int num = atoi(agrv[1]);
  9.         printf("\t pid\t ppid\t pgid\n");
  10.         printf("parent\t%d\t%d\t%d\n",getpid(),getppid(),getpgid(0));
  11.         for(i=0;i<num;i++)
  12.         {
  13.                 if(fork()==0)
  14.                 {
  15.             printf("-----------------------------\n");
  16.                         printf("child%d\t%d\t%d\t%d\n",i,getpid(),getppid(),getpgid(0));
  17.                 }
  18.         }
  19.         return 0;
  20.  
  21. }

执行
#./getpgid_example 2
请问会打多少行”—————————–\n”
我首先因为粗心的原因,按原书思路,不加思索就是2行,因为只会创建2个子进程。
看结果
parent  27049   21267   27049
—————————–
child0  27050   27049   27049
—————————–
child1  27051   27050   27049
—————————–
child1  27052   27049   27049
其实不然,n 与行数的关系是 行数=2^n-1 (n是2的指数)
#./getpgid_example 5 则会打印 2^5-1=31行。

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>