fork和thread有什么区别?

Pav*_*mar 88 c multithreading fork process

谁能解释一个fork和一个线程之间的区别?

Dac*_*cav 85

fork为您提供了一个全新的流程,它是当前流程的副本,具有相同的代码段.随着内存映像的更改(通常这是由于两个进程的不同行为),您可以分离内存映像(Copy On Write),但可执行代码保持不变.除非使用某些进程间通信(IPC)原语,否则任务不共享内存.

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

  • 您可能希望将"当前进程的副本"称为子进程. (3认同)

Gee*_*ide 73

叉子:

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

最简单的分叉示例是在unix/linux上运行shell命令时.每次用户发出命令时,shell都会分叉子进程并完成任务.

发出fork系统调用时,会创建与父进程对应的所有页面的副本,由OS为子进程加载到单独的内存位置,但在某些情况下,这不是必需的.与'exec'系统调用一样,不需要复制父进程页面,因为execv会替换父进程本身的地址空间.

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

  • 子进程将拥有自己唯一的进程ID.
  • 子进程应拥有它自己的父文件描述符副本.
  • 父进程设置的文件锁不应由子进程继承.
  • 在父进程中打开的任何信号量也应在子进程中打开.
  • 子进程应拥有父对象的消息队列描述符的副本.
  • 孩子将拥有自己的地址空间和记忆.

主题:

线程是轻量级进程(LWP).传统上,线程只是一个CPU(以及其他一些最小状态)状态,其中包含剩余的进程(数据,堆栈,I/O,信号).线程比"分叉"或产生新进程所需的开销更少,因为系统不会为进程初始化新的系统虚拟内存空间和环境.虽然在多处理器系统上最有效,其中流程可以安排在另一个处理器上运行,从而通过并行或分布式处理获得速度,但在单处理器系统上也可以获得收益,这些系统利用I/O和其他可能停止进程的系统功能的延迟执行.

同一进程中的线程共享:

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

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

  • 一个进程可以有多个线程。如果进程中的一个线程调用 fork,那么 fork 的进程是否具有完全复制的内存,但只有调用线程在新进程中? (2认同)

Sam*_*ost 29

Dacav的答案非常好,我只想补充一点,并非所有线程模型都能为您提供真正的多处理.

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

这在多处理器/多核系统中很重要,因为这些类型的轻量级线程只能在单个核心上运行 - 您不会因为拥有多个线程而提高性能.

另一个区别是当一个线程阻塞(等待I/O或调用驱动程序的IOCTL)时,所有线程阻塞.

现在这种情况并不常见 - 大多数线程实现都使用不会遇到这些问题的内核线程 - 但是值得对完整性进行评估.

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

祝好运并玩得开心点!多线程既具有挑战性又有回报.

  • +1击中神经:"并非所有线程都能给你真正的多重处理" (7认同)

Var*_*ani 6

  1. 线程共享创建它的进程的地址空间; 进程有自己的地址空间.
  2. 线程可以直接访问其进程的数据段; 进程拥有自己父进程数据段的副本.
  3. 线程可以直接与其进程的其他线程通信; 进程必须使用进程间通信来与兄弟进程通信.
  4. 线程几乎没有开销; 流程有相当大的开销.
  5. 新线程很容易创建; 新流程需要重复父流程.
  6. 线程可以对同一进程的线程进行相当大的控制; 进程只能控制子进程.
  7. 对主线程的更改(取消,优先级更改等)可能会影响进程的其他线程的行为; 对父进程的更改不会影响子进程


ser*_*gio 5

线程是并行运行的函数,fork是父进程继承的新进程.线程很好地并行执行任务,而fork是独立的进程,也是同时运行的.线程具有竞争条件,并且控制信号量和锁或互斥锁,管道都可以在fork和thread中使用.