分叉与线程

时间:2013-05-03 08:23:15

标签: linux multithreading unix programming-languages fork

我之前在我的应用程序中使用过线程并且很好地了解它的概念,但是最近在我的操作系统讲座中我遇到了fork()。这与线程类似。

我谷歌搜索他们之间的差异,我开始知道:

  1. Fork只是一个看起来与旧进程或父进程完全相同的新进程,但它仍然是一个具有不同进程ID并拥有自己内存的不同进程。
  2. 线程是轻量级的,具有较少的开销
  3. 但是,我脑子里还有一些问题。

    1. 你应该什么时候更喜欢fork()而不是线程?反之?
    2. 如果我想作为孩子调用外部应用程序,那么我应该使用fork()或线程来执行吗?
    3. 在进行谷歌搜索时,我发现有人说在线程中调用fork()是件坏事。为什么人们想在类似的事情中调用线程内的fork()?
    4. fork()是否无法利用多处理器系统,因为父进程和子进程不同时运行?

3 个答案:

答案 0 :(得分:43)

分叉和线程方法之间的主要区别在于操作系统架构。在Unix设计的时代,分叉是一个简单,简单的系统,可以最好地满足大型机和服务器类型的要求,因为它在Unix系统上得到了普及。当Microsoft从头开始重新构建NT内核时,它更多地关注线程模型。因此,今天仍然存在显着差异,因为Unix系统在分叉时效率很高,并且Windows在线程方面效率更高。你可以在Apache中看到这个,它在Unix上使用prefork策略,在Windows上使用线程池。

特别针对您的问题:

  

你应该什么时候更喜欢fork()而不是线程?反之?

在Unix系统上,您执行的任务远比仅实例化工作程序要复杂得多,或者您需要单独进程的隐式安全沙箱。

  

如果我想作为孩子调用外部应用程序,那么我应该使用fork()或线程来执行吗?

如果孩子将使用相同的代码对父母执行相同的任务,请使用fork。对于较小的子任务,请使用线程。对于单独的外部进程,请不要使用它们,只需使用正确的API调用来调用它们。

  

在进行谷歌搜索时,我发现有人说在线程中调用fork()是件坏事。为什么人们想在类似的事情中调用线程内的fork()?

不完全确定,但我认为复制流程和大量子线程在计算上相当昂贵。

  

fork()是不是可以利用多处理器系统,因为父进程和子进程不同时运行?

这是假的,fork创建了一个新进程,然后利用OS任务调度程序中进程可用的所有功能。

答案 1 :(得分:22)

分叉过程称为重量级过程,而线程过程称为轻量级过程。

以下是它们之间的区别:

  1. 分叉进程被视为子进程,而线程进程被称为兄弟进程。
  2. 分叉进程与父进程不共享代码,数据,堆栈等资源,而线程进程可以共享代码但有自己的堆栈。
  3. 进程切换需要OS的帮助,但不需要进行线程切换
  4. 创建多个进程是一项资源密集型任务,而创建多个线程则是资源密集度较低的任务
  5. 每个进程可以独立运行,而一个线程可以读/写另一个线程数据。 线程和进程lecture enter image description here

答案 2 :(得分:8)

正如您所指出的,

fork()会产生一个新的流程副本。上面没有提到的是exec()通常会跟随的电话。这将使用新流程(新的可执行文件)替换现有流程,因此fork() / exec()是从旧流程生成新流程的标准方法。

e.g。这就是shell如何从命令行调用进程。您可以指定您的流程(例如ls)和shell分叉,然后执行ls

请注意,这与线程的操作级别非常不同。线程在进程内运行多行执行。分叉是一种创建进程的方法。