进程控制之fork函数

1.fork函数

  #inlcude <unistd.h>

  pid_t fork(void);

  由fork创建的新进程被称为子进程(child process)。fork函数被调用一次,返回两次。两次返回的唯一区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程ID。子进程是父进程的副本。父、子进程并不共享存储空间部分(数据空间,堆和栈)。父、子进程共享正文段。

  一般来说,在fork之后是父进程先执行还是子进程先执行是不确定的。解决的方法是使用信号是父、子进程同步。

2. 文件共享

   在重定向父进程的标准输出时,子进程的标准输出也被重定向。实际上,fork的一个特性是父进程的所有打开文件描述符都被复制到子进程中。

   在fork之后处理文件描述符有两种常见的情况:

   1) 父进程等待子进程完成。在这种情况下,父进程无需对其描述符做任何处理。

   2) 父、子进程各自执行不太的程序段。这种情况下,在fork之后,父子进程各自关闭不需要使用的文件描述符,这样不会干扰对方使用的文件描述符。

3. 父、子进程区别

   1) fork的返回值

   2) 进程ID

   3) 子进程的tms_utime, tms_stime, tms_cutime以及tms_ustime均被设置为0

   4) 父进程设置的文件锁不会被子进程继承

   5) 子进程的未处理的闹钟(alarm)被清除

   6) 子进程的未处理信号集设置为空集

4. fork失败的原因

   1) 系统已经有太多的进程

   2) 该实际用户ID的进程总数超过了系统限制

5. fork的应用

    1) 一个父进程希望复制自己,使父、子进程同时执行不同的代码段。例如,网络服务中,父进程等待客户端服务的请求。

    2) 一个进程要执行一个不同的程序。在这种情况下,子进程从fork返回后立即调用exec函数。

6. fork函数与vfork函数区别

   1) vfork函数也创建一个子进程,但是并不将父进程的地址空间完全复制到子进程中,因为子进程会立即调用exec(或exit),于是不会存放该地址空间。相反,在进程调用exec(或exit)前,它在父进程的空间中运行。

   2) vfork保证子进程先运行,在进程调用exec(或exit)之后进程才可能被调度运行。

7. fork与I/O函数见的交互关系

   先看一个小程序:

  

编译该程序,执行它,如下:

[wzhwho@local~]$ ./a.out

The secret that cannot say

before fork

pid = 1039, global = 7, val = 100

pid =1038, global = 6, val = 99

 

[wzhwho@local~]$ ./a.out > tmp

[wzhwho@local~]$ cat tmp

The secret that cannot say

before fork

pid = 1039, global = 7, val = 100

before fork

pid =1038, global = 6, val = 99

 

   write函数是不带缓冲的,因为fork之前调用write,所以其数据写到标准输出上只有一次。但是,标准I/O函数是带缓冲的。如果标准输出到终端时,它是行缓冲的,否则它是全缓冲的。当以交互方式运行该程序时,只得到该printf输出的行一次,原因是标准输出缓冲区由换行符来冲洗。当将标准输入重定向到一个文件时,去得到了printf输出行两次,是因为在fork前调用了printf一次,但当调用fork时,该行数据仍在缓冲区中,然后将父进程数据空间复制到了子进程时,该缓冲区也被复制到子进程中。当每个进程终止时,最终会冲洗其缓冲区中的副本。

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值