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

本文关键字:环境 设置 2个 变量 多线程 可以使 我可以 | 更新日期: 2023-09-27 18:29:01

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

我有多个线程从多核/cpu机器上的文件中读取(1个线程/文件)。一个文件可以包含刻度(出价/要价信息等)或条形(打开、高、低、关闭、vol)。我有一个worker类,它是读取文件的线程doWork的目标。工作者/线程只能读取条形图或刻度线,而不能同时读取两者,即1个文件将是所有条形图或所有刻度线等。每个线程将刻度线或条形图读取到自己的缓冲区中。

出于性能原因,我不使用泛型或继承(我可能会同时实现这两者并测试性能)。我使用环形缓冲区(每个缓冲区只有1个读写线程,所以这是安全的)。相反,我也会检查员工的类型,以确定我是否有勾号或条形图。

我想做的是按时间顺序处理勾号或条形图。。因此,当一个工作线程向其缓冲区添加一个条形图/记号时,我希望它获得时间并与全局mintime进行比较,如果时间较短,则设置全局mintime并设置全局索引变量,这样主线程就会知道在其列表中使用哪个索引来按顺序获取数据。

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

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

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

伪码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();{
}

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

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

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

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

侧钞

出于性能原因,我不使用泛型或继承

这太傻了。仿制药是为了提高性能而设计的。应尽量避免提前进行此类代码优化。继承不会在您应该关心的范围内降低性能。