叉和线有什么区别?
任何人都可以解释一个fork和一个线程之间的区别吗?
fork为您提供了一个全新的进程,它是当前进程的副本,具有相同的代码段。 随着内存映像的变化(通常这是由于两个进程的行为不同),你会得到内存映像的分离(Copy On Write),但是可执行代码保持不变。 任务不会共享内存,除非他们使用某个进程间通信(IPC)原语。
一个进程可以有多个线程,每个线程在进程的相同上下文中并行执行。 内存和其他资源在线程之间共享,因此共享数据必须通过一些原始和同步对象(如互斥体 , 条件variables和信号量 )来访问,以避免数据损坏。
叉子:
叉只不过是一个新的过程,看起来完全像旧的或父过程,但它仍然是一个不同的过程,具有不同的过程ID和拥有自己的记忆。 父进程为subprocess创build一个单独的地址空间。 父进程和subprocess都具有相同的代码段,但彼此独立执行。
分叉的最简单的例子是当你在shell / unix / linux下运行命令时。 每次用户发出命令时,shell都会分叉一个subprocess,任务完成。
当发出fork系统调用时,创build与父进程对应的所有页面的副本,由subprocess的OS将其加载到单独的内存位置,但是在某些情况下,这不是必需的。 就像在'exec'系统调用中一样,不需要复制父进程页面,因为execv替代了父进程本身的地址空间。
几点关于分叉的事情是:
- subprocess将拥有自己独特的进程ID。
- subprocess应该有它自己的父文件描述符副本。
- 由父进程设置的文件锁不应该被subprocessinheritance。
- 任何在父进程中打开的信号量也应该在subprocess中打开。
- subprocess应该有它自己的父节点的消息队列描述符副本。
- 孩子将拥有自己的地址空间和内存。
主题:
线程是轻量级进程(LWP)。 传统上,线程只是一个CPU(和其他一些最小状态)的状态,包含遗留(数据,堆栈,I / O,信号)的进程。 线程所需的开销比“派生”或产生新进程要less,因为系统不会为进程初始化新的系统虚拟内存空间和环境。 虽然在多处理器系统中最有效的方法是将stream程安排在另一个处理器上运行,从而通过并行处理或分布式处理获得速度,但在单处理器系统上也可以获得增益,这些系统利用I / O和其他系统function的延迟,执行。
线程在同一个进程中共享:
- stream程说明
- 大部分数据
- 打开文件(描述符)
- 信号和信号处理程序
- 当前工作目录
- 用户和组ID
更多细节可以在这里find。
达卡夫的答案非常好,我只想补充一点,不是所有的线程模型都能给你真正的多处理。
例如,Ruby的默认线程实现不使用真正的OS /内核线程。 相反,它通过在单个内核线程/进程内的Thread对象之间进行切换来模仿multithreading。
这在多处理器/多核系统中很重要,因为这些轻量级线程只能在单个核心上运行 – 从multithreading获得性能提升的方式并不多。
另一个有所不同的地方是当一个线程阻塞(等待I / O或者调用驱动程序的IOCTL)时,所有的线程都被阻塞。
现在这不是很常见 – 大多数线程实现使用不受这些问题影响的内核线程 – 但是为了完整性,这是值得的。
相比之下,fork为您提供了另一个在原始进程正在执行的同时可以在另一个物理CPU上运行的进程。 有些人认为IPC更适合他们的应用程序,其他人更喜欢线程。
祝好运并玩得开心点! multithreading既是具有挑战性的,也是有益的。
线程是并行运行的函数,fork是父进程inheritance的新进程。 线程并行执行任务是很好的,而叉是独立的进程,也是同时运行的。 线程有竞态条件,并在那里控制信号量和锁或互斥体,pipe道可以在叉和线程中使用。
- 线程共享创build它的进程的地址空间; 进程有自己的地址空间。
- 线程可以直接访问其进程的数据段; 进程拥有其父进程的数据段的自己的副本。
- 线程可以直接与其进程的其他线程通信; 进程必须使用进程间通信与兄弟进程进行通信。
- 线程几乎没有开销; 进程有相当大的开销。
- 新线程很容易创build; 新stream程需要重复父stream程。
- 线程可以对相同进程的线程进行相当程度的控制; 进程只能对subprocess进行控制。
- 对主线程的更改(取消,优先级更改等)可能会影响进程的其他线程的行为; 父进程的更改不会影响subprocess