【问题标题】:performance - multithreaded or multiprocess applications性能 - 多线程或多进程应用程序
【发布时间】:2013-05-16 06:16:42
【问题描述】:

为了在 linux 上开发高度网络密集型的服务器应用程序,首选哪种架构?这个想法是这个应用程序通常会在具有多核(虚拟或物理)的机器上运行。考虑到性能是关键标准,选择多线程应用程序还是多进程设计的应用程序更好?我确实知道从多个进程共享资源和同步访问这些资源需要大量的编程开销,但如前所述,整体性能是关键要求,因此我们可以忽略这些事情。并且编程语言是 C/C++。

我听说即使是多线程应用程序(单个进程)也可以利用多个内核并在不同内核上独立运行每个线程(只要不存在同步问题)。而这个调度是由内核完成的。如果是这样,多线程应用程序和多进程应用程序之间的性能差异不是很大吗? Nginx 采用多进程架构,速度确实很快,但是多线程应用能获得同样的性能吗?

谢谢。

【问题讨论】:

    标签: linux multithreading multiprocessing


    【解决方案1】:

    Linux 上的进程和线程彼此非常相似——主要区别在于整个虚拟内存是共享的,而信号处理等某些方面也不同。

    这使得线程之间的上下文切换成本更低(不需要昂贵的 MMU 重新加载等),但不一定会导致速度差异很大(尤其是在线程创建之外)。

    对于设计一个高度网络密集型的应用程序,基本上唯一的解决方案是使用事件架构(否则你会因为大量进程/线程而使系统陷入困境并花费更多时间在他们的管理而不是实际运行工作代码),您可以在其中对套接字上的 I/O 做出反应,并根据哪些套接字表现出活动来执行适当的操作。

    关于在这种情况下面临的问题的著名文章是“C10k 问题”,可从http://www.kegel.com/c10k.html 获得 - 它描述了不同的 I/O 方法,因此尽管有点过时,但它是一个很好的介绍。

    不过,在深入研究类似反应器的设计之前要小心——它们可能会变得笨拙和复杂,所以看看你是否不能使用提供更好抽象的库/语言(Erlang 是我个人最喜欢的,像 Go 这样的带有协程的语言也很有用)。

    【讨论】:

    • @p-l:感谢您的回答。是的,计划是使用基于偶数的架构并根据网络事件采取行动。并且在运行时不会创建额外的线程和进程。鉴于此,您是否认为多线程和多进程应用程序之间没有性能差异?例如:如果有一个具有 4 核的系统,那么两种架构之间的性能不会有任何明显的差异吗?
    • 最大的可能差异在于调度,可以通过任务的 cpu 亲和性进行修改,将每个任务(线程/进程)固定到特定的 cpu。更多差异可能来自服务器进程完成的实际工作以及它如何与网络部分交互。内存访问方式可能存在差异,但与线程/进程差异相关的差异较少,因为在 NUMA 系统上通常共享内存 - 尽管当前内核可能支持在不同 NUMA 区域中复制代码段(他们过去确实为内核本身提供了这个)。
    【解决方案2】:

    如果您的线程彼此独立地完成这项工作,那么在 linux 下,根本没有理由不使用多个进程。多个进程会增加您的内存使用量,因为每个进程都有自己的私有内存空间,但另一方面,在独立线程之间共享内存空间是更糟糕的决定。线程与进程之间的上下文切换通常对进程而不是线程做得更好,尽管它有点依赖架构和代码。进程是安全的,不会被锁和互斥体序列化。在 Linux 中,进程更易于管理和交互。这是一份您可能会感兴趣的好文档 (http://elinux.org/images/1/1c/Ben-Yossef-GoodBadUgly.pdf)。

    【讨论】:

    • 感谢参考文档,很有帮助。我相信线程更快的看法来自早期的 Windows 环境,它从头开始创建完整的进程,不像 Linux fork 仅仅复制堆栈并且最初子进程和父进程共享相同的内存段。我认为除非进行 exec 调用,否则代码将继续在所有子进程和父进程之间共享。
    猜你喜欢
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 2023-03-07
    • 2021-09-08
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 2011-12-30
    相关资源
    最近更新 更多