信号量范围和行为

时间:2012-04-19 21:05:02

标签: c# multithreading scope semaphore

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

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

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

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

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

此外,信号量应该是什么?我是否可以通过让他们共享一个共同的信号量来限制其他任务组?这是对信号量意图的严重混淆,还是它的意图。它上面有很多信息,但是以简化的抽象形式,我找不到一篇描述何时以及如何使用这些东西的文章。

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

2 个答案:

答案 0 :(得分:3)

范围约束,(如果你可以调用它们!),是因为信号量是可以使用(未​​命名),用于线程间通信或(命名)或进程间的操作系统内核同步原语,(组装间)通讯。该语言不能限制命名变体的范围。

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

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

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

答案 1 :(得分:0)

您似乎假设唯一的解决方案是对内置.NET线程池进行分区。如何为任务组使用单独的自定义线程池?有关Jon Skeet的示例代码,请参阅this link