2012-02-27 76 views
9

会不会是一个很大的区别这两scenarious:应用多线程与多实例 - 可以选择哪一种?

  1. 一个实例创建100个线程来处理一些工作在同一应用程序的
  2. 10个实例创建10个线程每处理作业(总100)

两种情况下的线程数都是相同的。这是一种表现还是对某种形式的改进?

实例 - 例如控制台应用程序,所以在第二种情况下,它将012控制台应用程序运行。每个应用程序都有自己的文件夹 。

+3

3.不要创建100个同时活动的线程,除非您在Cray上使用大量处理器。 – 2012-02-27 22:35:21

+0

你的流程需要沟通吗? – Jimmy 2012-02-27 23:35:27

+0

对不正确的答案(已删除)进行分析。我测试了上述场景,发现单进程多线程应用程序实际上比多进程应用程序更快。会试着自己理解原因。 – Jimmy 2012-02-28 01:21:30

回答

4

一个线程使用比一个进程更少的资源,所以理论上选项1会更好。然而,你可能不会注意到两者之间有太大的区别,因为100个独立的线程处理所有同时运行,并争取相同的操作系统资源几乎保证让你的系统停下来。

我会选择选项3-一个包含相当小的线程池的进程。这样,一些工作将同时执行,其他工作将排队等待轮到他们。如果要运行大量的工作,这种方法也可以很好地扩展。

ThreadPool类,在其顶部上的许多较高级别的抽象或优选,一个(例如,task library,甚至普通老式asynchronous delegates)。

0

这样一个奇怪的问题,很难找到实际的应用..但我会想象从性能的角度来看,选项1会更好。运行同一个应用程序的10个实例,看起来会有更多的工作要做。 (清理,注册,控制台打开等)

编辑* 因为使用选项1,您可以排队工作并让线程处理负载。

2

选项2具有(至少)以下开销:

  • 更多处理对象每个进程静态存储器
  • 更多
  • CLR和即时编译代码的多个实例
  • 上下文切换需要切换地址空间(非常昂贵)
  • 分享应用程序数据结构的机会较少
  • 您需要cr oss进程通信。简单的方法调用成为IPC操作
  • 为臭虫通过thread-无内置负载平衡你
  • 更多的机会(IPC通信,叉炸弹,...)
  • 更糟的可调试
  • 更多的工作池
  • 较难和更容易出错的同步。减少内置的东西和慢

为什么你会选择(2)如果你可以选择(1)?有正当理由,但这些都是比较特殊的:

  • 您需要能够容忍任意内存损坏。这是不正常的情况(根本不是!)
  • 你需要杀死线程的能力。对于单线程来说,这在CLR内部不能可靠地完成。但是你可以协同工作,无论如何这通常是更好的选择
  • 你的线程需要在不同的用户和其他用户下运行。这几乎不会发生。

一般来说,过程越少越好。

+0

我通过编辑添加了很多东西。 – usr 2012-02-27 22:39:07

1

是的,这将是一个很大的区别。每种方法都有优点和缺点:

  • 内存消耗。显然,10个进程中的每一个都会要求创建自己的地址空间 等。虽然 沟通/同步线程相对容易(您可以使用关键部分,其中 是最有效的方法之一),但在 进程之间执行操作将更困难。在10个进程和10个线程的情况下,您必须执行两种方法。
  • 崩溃。如果其中一个线程正在执行 错误,则整个过程都会死亡。

我个人更喜欢一个进程/许多线程。但是,这实际上取决于任务。

+0

OP是否说他的流程需要沟通? – Jimmy 2012-02-27 23:27:55

+0

我测试了实际场景,发现多个进程较慢。你是对的。我删除了我的不正确答案。 – Jimmy 2012-02-28 01:16:26

2

这取决于你在做什么,但在大多数情况下,选项1将具有最佳性能,并且将是最容易使用的。
为了给你一个更完整的答案,我需要了解以下内容:

  • 是100个线程都执行相同的任务?
  • 100个线程是否访问相同的数据?
  • 线程处理的任务是否会自然停机(等待另一个进程完成或资源可用)?
  • 线程处理的任务是否都尝试访问有限的资源(如硬盘或网卡)?
  • 您的计算机可以同时处理多少个并发线程(例如,具有超线程的4个核心处理器可以处理8个线程,没有超线程的4个核心处理器可以处理4个线程)?
  • 如果线程出现问题会发生什么情况?进程是否崩溃,线程是否重新启动?

如果线程都执行相同的任务,让他们一起将是最终用户和开发人员后者更容易,因为一切都在一个地方。

如果线程都访问相同的数据,然后让他们在同一个进程可以让你线程之间共享数据,并降低内存足迹(修改数据时,虽然留意竞争条件)。您可能还可以组队线程从相同的块访问数据,所以一切都可以在CPU上缓存,减少内存延迟的影响,虽然这不是我会建议尝试。

由于许多答案都对如何实施项目提供咨询,知道如果每个线程设计,充分利用CPU正在运行或在所有的时间,如果这些都是做的工作少量之前的后台任务重新入睡将有助于我们针对您的情况提出正确的建议。

知道什么是硬件的过程将运行在将帮助我们提供正确的建议您的具体情况。

如果一个线程失败,会发生什么?如果线程每天失败一次,是否需要用户进行干预,停止进程并重新启动?如果是这样,那么在其他线程上完成的任何未保存的工作将会丢失。在这种情况下,让每个线程都在自己的进程中运行,只会让您失去失败的进程。


Christian Hayter的选项3有意义,但并不总是与C#相关。
如果你看一下documentation,它指出:

了操作系统的ThreadId有一个托管线程没有固定的关系,因为非托管主机可以控制托管和非托管线程之间的关系。具体而言,复杂的主机可以使用CLR Hosting API根据相同的操作系统线程安排多个托管线程,或者在不同的操作系统线程之间移动托管线程。

基本上这意味着.net框架将集中你的线程,如果它感觉就像这将是一个不错的主意。如果你的进程使用更多的线程,这很可能发生,而多线程进程之间的线程总数可能会保持非常相似。因此,我期望1进程,100线程解决方案使用更少的总线程,然后10个进程,每个10线程(大约10到40,但你必须检查)。

这就是说,框架将被猜测,所以在某些情况下,线程池将是一个更好的选择。请务必先阅读documentation,因为有些情况下不应使用线程池。有关泳池的快速教程可在MSDN上找到。还有一个讨论何时使用线程池的thread


如果您提供更多信息,我会尝试给出更准确的答案。否则选项1(可能选项3)在大多数情况下是更好的选择。