【问题标题】:multithread running on difference processes or same process?多线程在不同进程或相同进程上运行?
【发布时间】:2012-04-05 22:21:06
【问题描述】:

在我的 .net 多线程程序中,我想知道所有这些线程在同一进程或不同进程上运行? 如果它在同一个进程上,那么我假设一个进程在一个内核上运行,那么多线程如何利用我的四核 cpu 中的所有四个内核? 但是如果它在不同的进程上,因为我知道不同的进程和相同的进程有不同的数据共享机制,那么我为什么不需要在我的多线程程序中编写不同的代码来处理这个?有人能解释一下吗

我想再问两个类似的问题

当我打开任务管理器时,经常可以看到大约 800 个线程和 54 个进程,而我的 cpu 使用率只有 5%,而且我被告知每个内核一次只能执行一个线程。 我的 cpu 是一直在运行这 800 个线程,还是仅仅意味着 800 个线程在排队,等待 cpu 处理? 如果我想让我的多线程程序充分利用我的四核 cpu,我可以通过创建更多线程来提高 cpu 使用率吗(这似乎与一次只有一个线程一个核心的理论相矛盾)

【问题讨论】:

  • 请澄清您所说的数据共享机制是什么意思。

标签: c# multithreading process


【解决方案1】:

多线程意味着同一进程中有多个线程。
每个线程都可以分配给不同的核心。

但是所有线程都属于同一个进程,例如,如果其中一个线程将抛出未处理的异常,则该进程将与它的所有线程一起崩溃。

您可能已经阅读了一些相关信息,只需搜索 google 或 Wikipedia - Software Multithreading

【讨论】:

    【解决方案2】:

    单个进程可以使用多个线程;即使是基本的 .NET“hello world”控制台 exe 也可能使用 4 或 5。所以是的,一个进程可能会使用所有可用的内核如果你编写它来这样做

    因为它是同一个过程,所以数据共享是直接的,但是:如果您要更改值,则必须小心,否则可能会发生非常糟糕的事情。如果您要更改线程代码中的数据,则必须仔细同步访问(lock 等)。

    但是,您确实通常必须编写不同的代码来支持多线程。例外情况是当框架为您执行此操作时,例如,ASP.NET 或 WCF 可能会接收传入请求并将它们交给不同的工作线程,从而允许多个并发操作,即使您没有这样做以这种方式明确编码。这意味着在 ASP.NET 或 WCF 中,您需要小心共享状态,原因已经讨论过了。

    作为一个小补充,还要注意一个进程可以支持多个AppDomains;在这种情况下,进程的线程由调度程序随心所欲地在所有AppDomains 之间共享。

    【讨论】:

    • 但是hello world console exe不是多线程程序,怎么会使用4或5线程呢?我总是假设它只使用一个线程,除非我明确编写多线程程序
    • @VickyLiao 至少有一个线程必须运行才能让 hello world 工作,这就是主线程。您的假设是正确的:只使用一个线程,除非您明确编写多线程程序,但框架可能有几个其他线程隐含地需要运行您的程序。
    • @VickyLiao 正如 Lirik 所说,该框架也使用线程 - 用于 IO 和内部管理(GC、终结器等)。它还在一些地方使用了 ThreadPool(一组共享的可重用线程)
    • 控制台 exe 中的快速测试显示:4 个线程用于 IDE 外部的发布版本,12 个线程用于inside IDE 的调试版本。
    【解决方案3】:

    由该进程创建的线程是该进程的一部分。一个进程中的不同线程可以而且经常在不同的处理器或处理器内核上运行。

    【讨论】:

      【解决方案4】:

      在我的 .net 多线程程序中,我想知道所有这些线程 运行在同一个进程还是不同进程上?

      一个线程总是在一个进程中运行,但是,多个线程可以在一个进程中运行,并且每个线程可以由不同的内核处理。

      如果你只有一个核心,并不意味着它不能运行多个线程,它只是意味着这个核心不能执行多个线程同时。如果你看一下上面的图片,你会注意到:

      1. 线程 #1 执行了一段时间。
      2. 线程 #1 “停止”。
      3. 线程 #2 执行了一段时间。
      4. 线程 #2 “停止”。
      5. 线程 #1 再次执行了一段时间。

      这说明了当一个核心运行多个线程时会发生什么:核心一次只执行一个线程,但是为了让两个线程都运行,核心必须执行context switching。换句话说:核心从线程 1 运行一些命令,切换到线程 2 并从中运行一些命令,然后切换回线程 1 执行更多命令。

      杂耍橘子:

      一个很好的比喻是玩橘子:从技术上讲,你只有两只手,每只手一次只能拿着一个橘子,所以你最多可以拿着两个橘子。在这种情况下,征税部分正在持有橙子。然而,如果你把一个橙子扔到空中,那么你可以在第二个橙子在空中的时候拿着第三个橙子。你把橘子扔得越高,你可以玩的橘子就越多。更准确地说:橙子回到你手中的时间越长,你可以玩弄的橙子就越多。当然,你可能无法同时处理大量的橙子,因为扔橙子比拿着它需要更多的能量。

      本质上,您的 CPU 正在处理线程:线程在 CPU 上执行代码的时间越长,CPU 可以“处理”的线程就越多。如果一个线程正在等待 I/O(例如数据库请求),那么 CPU 可以同时执行另一个线程的代码。这和你在任务管理器中看到 54 个进程和 800 个线程的原因是一样的:很多 这些线程中有一些正在做不受 CPU 限制的事情。

      睡觉:

      是我的 CPU 一直在运行这 800 个线程,还是只意味着 800 线程正在排队,等待 cpu 处理?

      您在任务管理器中注意到的许多线程都处于空闲/睡眠状态,因此它们使用的 CPU 很少(如果有的话)。但是,正在运行的 会在上下文切换的情况下执行(如果线程数多于内核数,这是大多数情况下的情况)。有很多事情会导致线程空闲/休眠,以橙色杂耍为例。

      CPU 利用率:

      如果我想让我的多线程程序充分利用我的四核 cpu,可以 我通过创建更多线程来提高 cpu 使用率(这似乎与 理论上一次只有一个线程一个核心)

      它变得棘手:)。想象一下,你有保龄球而不是橘子:这对你的手来说非常费力,所以即使你尝试过,你也可能无法握住超过 2 个保龄球,更不用说玩第三个了。在最大负载下,您只能握住与您的手一样多的物体。 CPU 也是如此:在最大负载下,CPU 只能执行与内核一样多的线程。

      您可以运行比内核数更多的线程的原因是线程没有将最大负载放在内核上。如果您的线程受 CPU 限制,即它们执行一些 繁重 计算工作并且它们对核心 100% 征税,那么您只能运行与核心一样多的线程。但是,CPU 是您计算机中最快的东西,您的线程可能正在访问计算机中比您的 CPU 慢得多的其他部分(硬盘、网卡等),因此您可以运行更多线程。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-18
        • 1970-01-01
        • 2021-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多