Linux 中的线程与进程

新手上路,请多包涵

我最近听到一些人说,在 Linux 中,使用进程而不是线程几乎总是更好,因为 Linux 在处理进程方面非常高效,并且因为与线程相关的问题(例如锁定)非常多。但是,我很怀疑,因为在某些情况下,线程似乎可以带来相当大的性能提升。

所以我的问题是,当面对线程和进程都可以很好地处理的情况时,我应该使用进程还是线程?例如,如果我正在编写 Web 服务器,我应该使用进程还是线程(或组合)?

原文由 user17918 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 738
1 个回答

Linux 使用 1-1 线程模型,(对内核而言)进程和线程之间没有区别——一切都只是一个可运行的任务。 *

在 Linux 上,系统调用 clone 克隆一个任务,具有可配置的共享级别,其中包括:

  • CLONE_FILES :共享同一个文件描述符表(而不是创建副本)
  • CLONE_PARENT :不要在新任务和旧任务之间建立父子关系(否则,孩子的 getppid() = 父母的 getpid()
  • CLONE_VM :共享相同的内存空间(而不是创建 COW 副本)

fork() calls clone( least sharing ) and pthread_create() calls clone( most sharing ) . **

fork 由于复制表和为内存创建 COW 映射,成本比 pthread_create 高一点点,但是 Linux 内核开发人员已经尝试(并成功)最小化了这些成本。

在任务之间切换,如果它们共享相同的内存空间和不同的表,将比不共享它们便宜一点,因为数据可能已经加载到缓存中。然而,即使没有共享任何内容,切换任务仍然非常快——这是 Linux 内核开发人员试图确保(并成功确保)的另一件事。

事实上,如果你在一个多处理器系统上, 共享实际上可能对性能有好处:如果每个任务都在不同的处理器上运行,同步共享内存的成本很高。


\* 简化。 CLONE_THREAD 导致信号传递被共享(这需要 CLONE_SIGHAND ,它共享信号处理程序表)。

\*\* 简化。 There exist both SYS_fork and SYS_clone syscalls, but in the kernel, the sys_fork and sys_clone are both very thin wrappers around the same do_fork 函数,它本身是 copy_process 的薄包装。是的,术语 processthreadtask 在 Linux 内核中可以互换使用…

原文由 ephemient 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏