【发布时间】:2011-01-29 19:05:17
【问题描述】:
谁能解释分叉和线程之间的区别?
【问题讨论】:
标签: c process multithreading fork
谁能解释分叉和线程之间的区别?
【问题讨论】:
标签: c process multithreading fork
fork 为您提供了一个全新的进程,它是当前进程的副本,具有相同的代码段。随着内存映像的变化(通常这是由于两个进程的不同行为),您会分离出内存映像(写时复制),但可执行代码保持不变。任务不共享内存,除非它们使用一些 Inter Process Communication (IPC) 原语。
一个进程可以有多个线程,每个线程在进程的同一上下文中并行执行。内存和其他资源在线程之间共享,因此必须通过一些原语和同步对象(如mutexes、condition variables 和semaphores)访问共享数据,以避免数据损坏。
【讨论】:
Dacav 的回答非常好,我只是想补充一点,并非所有线程模型都能为您提供真正的多处理。
例如,Ruby 的默认线程实现不使用真正的操作系统/内核线程。相反,它通过在单个内核线程/进程中的 Thread 对象之间切换来模拟多个线程。
这在多处理器/多核系统上很重要,因为这些类型的轻量级线程只能在单核上运行 - 拥有多个线程并不能提高性能。
另一个不同之处在于,当一个线程阻塞(等待 I/O 或调用驱动程序的 IOCTL)时,所有线程都会阻塞。
这在当今并不常见 - 大多数线程实现使用不受这些问题影响的内核线程 - 但为了完整性,值得一提。
相比之下,fork 为您提供了另一个进程,该进程可在另一个物理 CPU 上同时运行,而原始进程正在执行。有些人发现 IPC 更适合他们的应用,而其他人则更喜欢线程。
祝你好运,玩得开心!多线程既具有挑战性又具有回报。
【讨论】:
线程是并行运行的函数,fork 是一个继承父进程的新进程。 线程很适合并行执行任务,而分叉是独立的进程,它们也同时运行。 线程有竞争条件,控制信号量和锁或互斥体,管道既可以用于 fork 也可以用于线程。
【讨论】:
Fork 只不过是一个看起来与旧进程或父进程完全一样的新进程,但它仍然是具有不同进程 ID 并拥有自己的内存的不同进程。父进程为子进程创建一个单独的地址空间。父子进程拥有相同的代码段,但彼此独立执行。
最简单的分叉示例是在 Unix/Linux 的 shell 上运行命令时。每次用户发出命令时,shell 都会派生一个子进程并完成任务。
当一个 fork 系统调用发出时,对应于父进程的所有页面的副本被创建,由操作系统为子进程加载到一个单独的内存位置,但在某些情况下,这不是必需的。与“exec”系统调用一样,不需要复制父进程页面,因为 execv 替换了父进程本身的地址空间。
关于分叉的几点注意事项是:
线程是轻量级进程 (LWP)。传统上,线程只是 CPU(和其他一些最小状态)状态,进程包含其余状态(数据、堆栈、I/O、信号)。与“分叉”或产生新进程相比,线程所需的开销更少,因为系统不会为进程初始化新的系统虚拟内存空间和环境。虽然在多处理器系统上最有效,其中进程流可以安排在另一个处理器上运行,从而通过并行或分布式处理获得速度,但在利用 I/O 延迟和可能停止进程的其他系统功能的单处理器系统上也发现了收益执行。
同一进程中的线程共享:
更多详情请见here。
【讨论】:
int a = 10占用内存位置1000在父地址空间中,那么即使在子进程中int a = 10 也会占用相同的第 1000 个内存地址。不过a的修改对于父子进程来说是不同的,每个子进程都可以修改a而不影响其他人,因为它是一个副本。