fork和thread有什么区别?


Answers:


94

分支为您提供了一个全新的过程,该过程是当前过程的副本,具有相同的代码段。随着内存映像的更改(通常是由于两个进程的行为不同),您会分离内存映像(写时复制),但是可执行代码保持不变。除非使用某些进程间通信(IPC),否则任务不会共享内存原语,。

一个进程可以具有多个线程,每个线程在该进程的同一上下文中并行执行。内存和其他资源在线程之间共享,因此共享数据必须通过一些原始对象和同步对象(例如互斥体条件变量信号量)进行访问,从而可以避免数据损坏。


3
您可能希望将“当前进程的副本”称为子进程。

1
但是,文本段通常是(虚拟的)共享的,甚至数据段也可以是写时复制的。
JE队列


76

叉子

Fork不过是一个看起来与旧流程或父流程完全相似的新流程,但是它仍然是具有不同流程ID并拥有自己内存的不同流程。父进程为子进程创建一个单独的地址空间。父进程和子进程都具有相同的代码段,但彼此独立执行。

最简单的派生示例是在Unix / Linux的shell上运行命令时。每次用户发出命令时,Shell都会派生一个子进程,并且任务完成。

发出fork系统调用时,将创建与父进程相对应的所有页面的副本,并由OS为子进程加载到单独的内存位置,但是在某些情况下,则不需要这样做。就像在“ exec”系统调用中一样,无需复制父进程页面,因为execv替换了父进程本身的地址空间。

关于分叉的几点注意事项是:

  • 子进程将具有其自己的唯一进程ID。
  • 子进程应具有其父文件描述符的自己的副本。
  • 由父进程设置的文件锁不得由子进程继承。
  • 在父进程中打开的任何信号量也应在子进程中打开。
  • 子进程应具有其自身的父消息队列描述符副本。
  • 子级将具有自己的地址空间和内存。

线程数

线程是轻量级进程(LWP)。传统上,线程只是一个CPU(以及其他一些最小状态)状态,而进程包含其余部分(数据,堆栈,I / O,信号)。线程比“派生”或生成新进程所需的开销更少,因为系统不会为进程初始化新的系统虚拟内存空间和环境。尽管在多处理器系统上最有效,在该系统上可以将流程调度为在另一个处理器上运行,从而通过并行或分布式处理来提高速度,但在利用I / O延迟和其他可能导致进程中断的系统功能的单处理器系统上也能找到收益。执行。

同一进程中的线程共享:

  • 工艺说明
  • 大多数数据
  • 打开文件(描述符)
  • 信号和信号处理程序
  • 当前工作目录
  • 用户和组ID

更多细节可以在这里找到。


2
一个进程可以有多个线程。如果进程中的线程之一调用fork,那么分叉的进程是否具有完全重复的内存,但是新进程中只有调用线程?
Michael


29

Dacav的回答很好,我只是想补充一点,并不是所有的线程模型都能为您提供真正的多处理能力。

例如,Ruby的默认线程实现不使用真正的OS /内核线程。相反,它通过在单个内核线程/进程内的Thread对象之间切换来模拟具有多个线程。

这在多处理器/多核系统上很重要,因为这些类型的轻量级线程只能在单个核上运行-通过拥有多个线程,您无法获得很多提高性能的方式。

另一个与众不同的地方是,当一个线程阻塞(等待I / O或调用驱动程序的IOCTL)时,所有线程阻塞。

如今这不是很常见-大多数线程实现都使用不受这些问题困扰的内核线程-但值得一提的是完整性。

相比之下,fork为您提供了另一个进程,该进程可以在原始进程执行时在另一个物理CPU上同时运行。有些人发现IPC更适合他们的应用程序,另一些人则喜欢线程。

祝好运并玩得开心点!多线程既有挑战性又有收获。


7
+1
令人不安

5

线程是并行运行的函数,fork是具有父级继承的新进程。线程是并行执行任务的好方法,而fork是独立的进程,也可以同时运行。线程具有竞争条件,可以控制信号量和锁或互斥体,管道可以同时用于fork和thread。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.