【问题标题】:Why would two processes have an advantage over 2 threads?为什么两个进程比 2 个线程有优势?
【发布时间】:2011-08-14 05:13:09
【问题描述】:

我有一个基于 MSMQ 的定位应用程序,我在其中接收来自现场单位的位置更新,并将它们处理并放入数据库中。

更新过程在数据库之外没有依赖关系,所以我的应用程序可以配置可变数量的线程。由于我希望进程在失败时保持稳健,因此我想处理尽可能多的消息,但不多(所以如果系统出现故障,我可以从离开的地方继续)。

我的应用程序工作正常,但我发现如果我增加用于处理消息的线程数,我的平均消息数处于一个级别(我使用性能计数器来衡量这一点),并且我让系统利用 50% 的可用 CPU 时间(我有一个具有 4 个物理内核和 8 个逻辑内核的 Core i7 820QM),但是如果我不增加线程,而是启动相同数量的进程,我会得到使用 100% 的 CPU 时间,并获得更高数量的平均事件处理。

可能是锁争用问题吗?与 Windows 7 处理超线程处理器的方式有关吗?我希望了解问题的性质,任何指针都将不胜感激。

注意:我在这个项目中使用 MSMQ、Rx 和实体框架。

【问题讨论】:

  • 你是如何提高线程数的?
  • 问题几乎肯定出在您对 Rx 的使用上。我认为 Rx 以一种并非所有内核都可以使用的方式协调您的线程(读取需要一些锁)。要获得一个想法,请在您的应用程序中多次中断并检查调用堆栈大部分时间在哪些方法中。这应该让您知道锁的位置。
  • @Wegged: new Thread(() => { ... } { IsBackground = true }.Start();
  • 我现在看到我使用的线程比我想象的要多。 BeginReceive/EndReceive 对从 MessageQueue 接收到的每条消息都使用一个线程进行接收,我正在该线程中处理我的消息(不是我想和想要的)。将线程加倍(不管创建更多线程的线程)仍然比加倍进程慢的事实。我猜是争吵,但我宁愿知道问题出在哪里。我的分析器运行,将时间放在我的更新方法中,而不是在框架中。

标签: c# multithreading entity-framework msmq system.reactive


【解决方案1】:

没有看到你的代码很难给出准确的答案,但我还是会添加一些可能性

首先,争用会产生巨大的影响,您使用的是什么锁定类型?

其次,.Net 框架可能会产生影响,因为 .Net 2.0 及更早的内核对象被用作锁定机制。这些需要内核转换来改变影响性能的状态。

【讨论】:

  • 我正在使用 .Net4。我的锁定策略基本上是,没有我管理的锁。我使用 FromAsyncPattern 和 BeginReceive、EndReceive 方法在 Rx observable 中接收来自 MSMQ 的消息。每个线程都有它自己的这个 observable 的副本,它指的是它自己的 MessageQueue 对象。基本上,我什么都不共享,所以我没有锁,但仍然不能通过使用更多线程来提高我的利用率,但我可以通过使用进程。可能有些东西是共享的,并且有我看不到的锁(可能是 EntityFramework 或 SqlConnection?我会尝试禁用连接池!)。
  • 在我看到我的处理没有在正确的线程中完成后,我改变了一些东西并确保情况确实如此。当我增加线程时,报告的争用数量越来越多,使得这些线程难以进展。由于争用的根源在库代码内部(而且我无法触及),因此我将切换到在这种情况下使用进程而不是线程。谢谢!
猜你喜欢
  • 2016-10-29
  • 2018-06-09
  • 1970-01-01
  • 2013-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-30
相关资源
最近更新 更多