【问题标题】:Semaphore scope and behavior信号量范围和行为
【发布时间】:2012-04-19 21:05:01
【问题描述】:

我从今天的一个较早的问题中了解了信号量,但我仍然在这里摸不着头脑。似乎没有关于全局和本地之外的范围的讨论,其中全局被定义为整个操作系统。

如果我有一个由多个程序集组成的应用程序,并且每个程序集有多个类,并且每个类都有一个私有静态信号量对象,具有不同的“队列”长度,如果我开始在我的应用程序线程池中排队不同的任务不同的地方,它是如何工作的?线程之间的行为如何?我看到的所有示例都在一个程序集中包含一两个类,但我并不清楚它是如何工作的。

我在整个应用程序中都使用线程池。它并行处理数据(向不同的人发送定制的电子邮件、生成大量定制的报告、从各种 Web 服务收集数据等),同时让我的界面保持响应,这是一件很棒的事情。

我的一个 Web 服务源将我限制为五个并发连接,我无法弄清楚如何将 Web 请求限制为 5 个活动线程,同时仍允许应用程序的其余部分根据需要使用其他线程。所以,我转向 SO,并询问如何做到这一点。建议的答案是使用信号量。

在那之前,我对信号量一无所知,所以我研究了它。它确实似乎限制了执行特定方法的线程数,但它如何与线程池管理器正确通信没有意义。如果我在我的 Web 请求功能上实现了一个信号量,并且我得到了等待执行 Web 服务调用的线程积压,那么线程池如何知道(它知道吗?)为其他进程发出更多线程?信号量的范围是私有的;它不应该看到对象。

此外,信号量是应该做的吗?我可以通过让它们共享一个共同的信号量来同样限制其他任务组吗?这是对信号量意图的粗俗化,还是它的意图。那里有很多信息,但都是简化、抽象的形式,我找不到一篇文章描述何时以及如何使用这些东西是合适的。

那么私有静态信号量如何与线程池通信,以便线程池知道是否生成另一个工作线程?可以?通过这样做,我会产生比解决方案更多的问题吗?我可以期望我的线程池在 Web 请求积压时表现出什么样的行为?它会为 Web 请求生成新线程,直到它“满”,从而降低其他方法的线程可用性?我可以让它不这样做吗?

【问题讨论】:

  • 这个问题很模糊。如果你有信号量、队列和线程,整个事情可能会以许多不同的方式表现,这取决于你的代码到底是什么。你能改写你的问题,让它更具体吗?
  • 好吧,让我把问题转到你身上。如果您有一个由多个程序集组成的应用程序,并且每个程序集有几个类,并且每个类都有一个包含 整数 的静态字段,并且这些整数都是不同的值,如何做到这一点工作?如果我向你提出这个问题,你甚至会如何开始回答这个问题?这个问题太模糊了,无法回答。问一个更具体的问题。
  • 静态整数不会停止线程。此类可以在线程池中保存一个线程,该线程应该自动处理应用程序可以支持的线程数,这一事实对我来说没有意义。也许少一点讽刺,多一点建设性的批评我需要如何集中我的问题会使这篇文章更有启发性。我对这个概念有困难,我不需要你告诉我我不明白。
  • @JeremyHolovacs:就我个人而言,我回避了这个问题,因为我真的不知道我的答案应该朝哪个方向发展。我认为你在这里提出了一个很好的问题。如果我能看到一些代码,我可以更容易地解释它发生了什么。尝试提出一个您不确定的示例并将其包含在您的问题中。

标签: c# multithreading scope semaphore


【解决方案1】:

范围限制(如果你可以这么称呼的话!)是因为信号量是操作系统内核同步原语,可以(未命名)用于线程间通信或(命名)或进程间通信,(组件间)通讯。该语言不能限制命名变体的范围。

一般来说,Google 上有大量关于信号量的信息。对于 .NET-wapped 的,MSDN。

进程间信令和通信通过。一般来说,命名信号量当然是可能的。如何在托管环境中执行此操作是另一回事。在非托管代码中,它通常涉及其他通信元素,例如共享内存区域和/或内存映射文件。你可能不应该去那里。

在尝试通过使任务在命名信号量上签名/等待来限制不同程序集中的线程池时要小心。如果您认为它可以解决您的应用程序的某些问题,请务必尝试一下,但至少有可能池线程计数、正在运行的池线程、在信号量上阻塞的池线程、在 IO 上的任务内部阻塞的池线程等。可能会变得不稳定。

【讨论】:

  • 我认为与自定义线程池相比,目前使用信号量几乎没有什么优势,至少在我将参与的任何场景中。感谢您的意见。
【解决方案2】:

您似乎假设唯一的解决方案是对内置的 .NET 线程池进行分区。为您的任务组使用单独的自定义线程池怎么样? Jon Skeet 的示例代码见this link

【讨论】:

  • 嗯,这可能是对另一个问题的回答,但这个问题更多的是关于线程池和信号量如何表现以及如何相互交互。
  • @JeremyHolovacs:没错,没错。然而,我试图暗示(如果有的话)Martin James 提出的关于为此目的使用命名信号量的担忧。如果我有这个问题要解决,我肯定会尝试使用单独的小线程池来处理 Web 请求。
  • 可能是这样的;但如果是这样,我首先看不到信号量的价值。为什么不为所有需要限制访问方法的东西创建自定义线程池?
  • @JeremyHolovacs:当默认(和单个).NET 线程池不支持您需要的开箱即用功能时,您需要替代方案。我要说的是,信号量是一种危险且复杂的信号量,而在此用例中,自定义线程池可能更容易采用和管理。
  • 嗯,在消费者之间共享多实例资源将是一个更“经典”的信号量问题;你可以找一个例子,咬牙切齿地发现你无所畏惧的自我:)
猜你喜欢
  • 2014-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-15
  • 2015-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多