Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无锁螺纹安全_C#_Multithreading_Image Processing - Fatal编程技术网

C# 无锁螺纹安全

C# 无锁螺纹安全,c#,multithreading,image-processing,C#,Multithreading,Image Processing,我的图像库中有以下代码,它使用处理器列表动态处理HttpModule捕获的图像 目前,为降低内存开销而创建的每个处理器只有一个实例,并且每个处理器都具有可写属性,这些属性有助于确定处理每个匹配的querystring参数和存储要处理的解析值的顺序 如您所见,我目前正在将方法功能包装在lock语句中,以防止来自HttpModule的不同线程覆盖处理器属性,尽管我知道这可能会成为瓶颈。我想知道的是:有没有一种设计模式或方法可以让我的处理器在没有锁的情况下实现线程安全 公共静态ImageFactory

我的图像库中有以下代码,它使用处理器列表动态处理
HttpModule
捕获的图像

目前,为降低内存开销而创建的每个处理器只有一个实例,并且每个处理器都具有可写属性,这些属性有助于确定处理每个匹配的querystring参数和存储要处理的解析值的顺序

如您所见,我目前正在将方法功能包装在
lock
语句中,以防止来自
HttpModule
的不同线程覆盖处理器属性,尽管我知道这可能会成为瓶颈。我想知道的是:有没有一种设计模式或方法可以让我的处理器在没有锁的情况下实现线程安全

公共静态ImageFactory自动处理(此ImageFactory)
{
if(工厂应处理)
{
//TODO:这将成为速度的瓶颈。找到一个更快的方法。
锁定(同步锁定)
{
//获取一个包含所有图形处理器的列表
//已解析并匹配查询字符串。
列表=
ImageProcessorConfig.Instance.GraphicsProcessor
.Where(x=>x.MatchRegexIndex(factory.QueryString)!=int.MaxValue)
.OrderBy(y=>y.SortOrder)
.ToList();
//循环并处理图像。
foreach(列表中的IGraphicsProcessor graphicsProcessor)
{
factory.Image=graphicsProcessor.ProcessImage(工厂);
}
}
}
返回工厂;
}

您可能对生产者-消费者队列感兴趣。通常,您的
HttpModule
将接收事件(生产者)并将它们排队到
IGraphicsProcessor
的一个或多个实例(消费者)

这是规范的、最简单的生产者/消费者队列实现:


如果您打算消除锁定,您应该使用无锁队列实现体验生产者/消费者队列,例如.NET 4.0中的
System.Collections.Concurrent.ConcurrentQueue

或者您需要通过不使用多个处理器来降低内存压力(然后您确实需要允许至少一个给定的处理器完成它当前的工作),或者您需要完全并发

除非有明确的理由不这样做,否则我将允许每个图像处理器有多个实例。确保处理器尽早释放对其正在处理的数据的引用,以允许GC以最佳方式运行。这具有简单性和CPU核心利用率高的优点


如果有明确的理由只允许每个处理器有一个实例,您可以通过避免在所有处理器完成工作之前锁定的当前情况来改进代码。相反,您可以有一种机制,在当前项目完成后,请求每个处理器处理下一个项目。@anthony's sugge使用生产者/消费者模式似乎是解决这一问题的可靠方法。请记住,使用这种方法,您仍然会在每个单独过滤器的吞吐量上遇到瓶颈,并且可能无法最佳利用所有CPU内核。

您有证据证明这是一个瓶颈吗?不要浪费宝贵的时间想出危险的解决方案对于您没有的问题,还有一些棘手的解决方案。如果这是一个瓶颈,那么解决方案的第一次尝试应该是将尽可能多的工作转移到锁之外,而不是试图消除锁。非争用锁非常快;我们谈论的是纳秒。争用锁非常昂贵;您可以通过在锁内没有做太多的工作。老实说,我没有。我本以为会这样。我已经对ImageFactory类进行了优化,这样它就不需要在
Bitmap
s周围使用任何锁,而且考虑到我可能正在处理这些锁,因此没有尽可能优化流程似乎是浪费时间的图片的用法。我不知道它们有那么快。我现在来看看。我实际上在另一个选项卡中打开了第一页。只有一个实例背后的另一个主要原因是可扩展性。我在应用程序启动时加载并创建
IGraphicsProcessor
接口的所有实例。想法是在库中,可以通过drop-in dll进行扩展。如果实例化实例的成本很高,则可以使用对象池来管理预初始化对象的N个实例。如果实例化实例的成本不高,则没有理由预创建它们。您是否有具体的度量(或对未来插件的期望)初始化开销会很高吗?当然不会。任何未来的实现都应该是轻量级的。不过,目前,每次调用该方法时,我都必须创建它们的实例,以便使用每个方法中的正则表达式来解析querystring。似乎处理器可以处理哪些参数的知识可能会被忽略作为实现类的静态属性保留。我认为不需要实例数据来进行确定。您可以重构以不需要实例来确定处理器顺序。