关闭

fork详解

81人阅读 评论(0) 收藏 举报
分类:

这个函数通过调用 fork(2) 系统调用,从一个进程中创建两个进程。如果它成功,该函数给 父进程返回新创建的子进程 ID,而给子进程返回0。如果系统没有足够的资源分配一个新的 进程,那么调用失败并返回undef。文件描述符(以及有时候还有在那些描述符上的锁)是共享的,而所有其他的东西都是拷贝的——或者至少看起来是那样的。
在早于 5.6 版本的 Perl 里,未冲刷的缓冲区在两个进程里都是没有冲刷的,这就意味着你需要在程序的早些时候在一个或多个文件句柄上设置 $| 以避免输出重复。
一个产生子进程然而有检查“cannot fork”错误的近乎没有毛病的方法是:

  1.    use Errno qw(EAGAIN);
  2.    FORK:{
  3.      if ($pid = fork) {
  4.        # 父进程在此
  5.        # 在 $pid 里可以看到子进程的进程id
  6.      }
  7.      elsif (defined $pid) {   # 如果定义了,$pid在这里是 0
  8.        # 子进程在此
  9.        # 你可以用 getppid 在这里获取父进程的pid
  10.      }
  11.      elsif ($! == EAGAIN) {
  12.        # EAGAIN 是认为可以恢复的 fork错误
  13.        sleep 5;
  14.        redo FORK;
  15.      }
  16.      else {
  17.        # 奇怪的 fork 错误
  18.        die "Can't fork: $!\n";
  19.      }
  20.    }

这些预防措施在那些做隐含的 fork(2) 的操作上是不必要的,比如 system,反勾号,或者把一个进程当作一个文件句柄打开,因为 Perl 在为你做 fork 的时候碰到临时的失败会自动重新 尝试 fork。要注意记得使用exit 结束子进程的代码,否则子进程会不小心地离开条件块并且 开始执行原来只是想让父进程执行的代码
如果你 fork 以后再也不等待你的子进程,那么你就会积累僵死进程(那些父进程还没等待它们 的退出进程)。在一些系统上,你可以通过设置$SIG{CHLD} 为“IGNORE”来避免这些;在 大多数系统上,你必须 wait 你的垂死的子进程。参阅 wait函数获做这些的例子,或则后参阅 第十六章的“信号”一节获取更多关于 SIGCHLD 的信息。
如果一个派生出来的子进程继承了系统文件描述符,象 STDIN 和 STDOUT 等,它们又和一个远程的管道或者套接字连接,那么你可能不得不在子进程里把他们重新打开到 /dev/null。这是因为即使父进程退出,子进程仍将带着这些文件句柄的拷贝继续生存。而远端服务器(比如说,一个 CGI 脚本或者一个从远程 shell发起的后台任务。)就会挂起,因为它仍然等待所有拷贝关闭。 重新把系统文件句柄打开成别的什么东西可以修补这个问题。
在大多数支持 fork(2) 的系统上,人们做了大量努力把它变得尽可能地高效(比如,数据页的写时拷贝(copy-on-write)技术),而它也成了过去几十年来多任务领域的典范。但是 fork函数可能并没有有效地(甚至可能是根本没有)在那些不象 Unix 的系统上实现。比如, Perl 5.6 甚至在 Microsoft系统上都模拟了一个合适的 fork,但是并不能保证可以达到很好 的性能。可能用 Win32::Process模块的时候,你的运气会好一些。


转自:http://www.perlcn.com/perlbc/perljj/1334.html
0
0
查看评论

linux操作系统fork详解

一、fork入门知识      一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。 &#...
  • sinat_35925219
  • sinat_35925219
  • 2016-08-21 10:46
  • 687

关于linux下fork()的底层实现(详解)

fork()系统调用通过复制一个现有进程来创建一个全新的进程(进程的另外一个名字叫做任务)。进程被存放在一个叫做任务队列的双向循环链表中。 链表中的每一项都是类型为task_struct称为进程描述符的结构。(它包含一个具体进程的所有信息)进程描述符的存放: 内核通过一个唯一的进程标识值或PID...
  • hello_bravo_
  • hello_bravo_
  • 2016-10-21 21:24
  • 1560

深入分析fork的执行过程(Linux-0.11内核)

在上一篇文章中简单分析了fork、pause等系统调用的实现,怀着对fork在父子进程中返回不同值的好奇,本文中将深入分析fork的执行过程以及如何实现在父子进程中返回不一样的值(父进程---子进程ID,子进程----0)。 为了分析fork,可以从它定义处开始一步一步的分析它执行的过程以及堆栈内容...
  • u010132427
  • u010132427
  • 2016-08-09 00:54
  • 746

linux中fork()函数详解(原创!!实例讲解) 讲得很好啊!!!

原文地址: http://blog.csdn.net/jason314/article/details/5640969 一、fork入门知识      一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原...
  • xulingxin
  • xulingxin
  • 2016-12-02 21:27
  • 260

多线程(五) Fork/Join框架介绍及实例讲解

1. 什么是Fork/Join框架Fork/Join框架是Java7提供了的一个用于并行执行任务的框架, 是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。我们再通过Fork和Join这两个单词来理解下Fork/Join框架,Fork就是把一个大任务切分为若干子任务并行...
  • lishehe
  • lishehe
  • 2015-06-19 18:00
  • 7556

java Fork/Join框架实例详解

简介通常,使用Java来开发一个简单的并发应用程序时,会创建一些Runnable对象,然后创建对应的Thread 对象来控制程序中这些线程的创建、执行以及线程的状态。自从Java 5开始引入了Executor和ExecutorService接口以及实现这两个接口的类(比如ThreadPoolExec...
  • qilixiang012
  • qilixiang012
  • 2015-05-06 23:02
  • 2280

Linux下进程的创建过程分析(_do_fork/do_fork详解)--Linux进程的管理与调度(八)

日期 内核版本 架构 作者 GitHub CSDN 2016-05-12 Linux-4.5 X86 & arm gatieme LinuxDeviceDrivers Linux进程管理与调度-之-进程的创建 参照 分析Linux内核创建...
  • gatieme
  • gatieme
  • 2016-06-02 20:27
  • 10023

fork函数详解(fork就是分叉的意思, 很形象)

转载地址: http://blog.sina.com.cn/s/blog_7582409f0100v6cp.html
  • stpeace
  • stpeace
  • 2014-08-24 23:56
  • 4929

Python 多进程 fork()详解

进程进程是程序的一次动态执行过程,它对应了从代码加载、执行到执行完毕的一个完整过程。进程是系统进行资源分配和调度的一个独立单位。进程是由代码(堆栈段)、数据(数据段)、内核状态和一组寄存器组成。 在多任务操作系统中,通过运行多个进程来并发地执行多个任务。由于每个线程都是一个能独立执行自身指令的不同...
  • SeeTheWorld518
  • SeeTheWorld518
  • 2015-11-04 16:02
  • 7884

Java-Fork/Join的简单例子(入门)

fork/join的使用 1、创建一个ForkJoinPool,forkjoin池。 ForkJoinPool forkJoinPool = new ForkJoinPool(); 2、创建一个task任务...
  • x_i_y_u_e
  • x_i_y_u_e
  • 2016-05-04 23:12
  • 888
    个人资料
    • 访问:26102次
    • 积分:812
    • 等级:
    • 排名:千里之外
    • 原创:55篇
    • 转载:11篇
    • 译文:0篇
    • 评论:2条
    文章分类