Skip to main content
 首页 » 编程设计

c#之我可以在多线程环境中使用互锁类设置 2 个变量吗

2024年02月13日39lhb25

我是编程/C# 的新手,有一个问题..

我有多个线程从多核/cpu 机器上的文件(1 个线程/文件)读取。文件可以包含价格变动(出价/询问信息等)或柱状图(开盘价、最高价、最低价、收盘价、成交量)。我有一个工作类,它是读取文件的线程 doWork 的目标。工作人员/线程只能读取柱形图或报价单,不能同时读取两者,即 1 个文件将全部为柱形图或全部报价单,等等。每个线程将报价单或柱形图读入其自己的缓冲区。

出于性能原因,我不使用泛型或继承(我可能会同时实现这两者并测试性能)。我使用环形缓冲区(每个缓冲区只有 1 个读取/1 个写入线程,所以这是安全的)。我还改为检查工作人员的类型以确定我是否有一个 tick 或 bar。

然后我想做的是按时间顺序处理一个报价单或条形图。因此,当一个工作人员将一个条形图/报价单添加到其缓冲区时,我希望它获得时间并与全局最小时间进行比较,如果它更少,然后设置全局最小时间并设置全局索引变量,以便主线程知道在其列表中使用哪个索引来按顺序获取数据。

我是否必须锁定(我避免使用环形缓冲区锁定)或以某种方式在 main 和 worker 中使用互锁类?

下面的代码是伪代码,因此并不完全正确,但希望您能理解。我正在寻找性能明智的最佳方式。

在我当前的实现中,在调用 Main 中的 GetTick 或 GetBar 之前,我在循环中对每个 simworker 调用 NextTime,然后对主工作器列表中的数组进行排序。我认为在工作线程本身中保持跟踪会更有效率,只是不确定同步。也许必须同步会消除任何好处。

伪代码EX:

Main() 
{ 
 List<worker>  workers = new List<worker>; 
 workers.Add(new worker(0,TICK)); 
 workers.Add(new worker(1,BAR)); 
 workers.Add(new worker(2,TICK)); 
 workers.Add(new worker(3,BAR)); //etcc, etc.. I do this in a loop. 
 //also start all workers - RunAsync.. then. 
 while(isrunning) 
 { 
   if(workers[index].workerType == TICK) 
   { 
      Tick= workers[index].GetTick(); 
      //process tick.. 
   }  
   else  
   { 
      Bar b = workers[index].GetBar(); 
       //process bar.. 
   } 
 } 
} 
 
public long mintime;     
public int index; 
 
 
class worker : BackgroundWorker  
{ 
  RingBuffer<tick> trb 
  RingBuffer<bar> brb 
 int idx; 
 public type workerType; 
 worker(int i, type wtype) 
 { idx = i; workerType = wtype }  
 
 doWork() 
 {while(reader.NextData) ;} //calls callback.. 
 
 callback(tick t) { trb.add(t); if(t.time < mintime) { mintime=t.time; index= idx}//??? 
 callback(bar b){   brb.add(b); if(b.time < mintime) { mintime=b.time; index =idx} 
 Tick GetTick() { trb.Read();} 
 Bar GetBar() {brb.Read();{ 
} 

请您参考如下方法:

如果您担心性能,您应该重新设计代码。

您的机器是多核的这一事实并不意味着您的读取速度更快。他们不是。事实上,如果你这样做,你的读取速度会变慢,这纯粹是因为有一个文件和许多线程想要读取不同的 block 。如果您的磁盘是镜像 RAID 阵列,您可能会获得更快的性能。否则多线程读取会降低性能,因为多个线程将竞争唯一的文件访问权限。

因此,您最好设计一个生产者(一个将 block 读入内存的线程)和多个消费者(读取共享内存并进行处理的线程)。

边注

I don't use generics or inheritance for performance reasons

这太傻了。泛型旨在提高性能。应尽量避免预先进行此类代码优化。继承不会降低您应该关心的规模的性能。