0

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

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

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

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

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

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

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

4

2 回答 2

3

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

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

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

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

于 2012-04-19T21:42:09.533 回答
0

您似乎假设唯一的解决方案是对内置的 .NET 线程池进行分区。为您的任务组使用单独的自定义线程池怎么样?请参阅此链接以获取 Jon Skeet 的示例代码。

于 2012-04-20T20:01:39.193 回答