C# 多线程问题

5
我试图简化问题,如下:
  1. 我有100多个文件需要读取并处理数据。
  2. 为此,我维护了一个包含文件名和位置的数组。
  3. 我生成线程来读取文件。
现在我的问题是,我想确保同时只有5个线程在运行,因为启动100个以上的线程不是一个好主意。
请告诉我应该使用什么方法来确保只有5个线程在工作,一旦其中一个完成就可以启动新的线程。
谢谢大家。

为什么要求同时只有5个线程工作? - Andrew
我想以后可以进行配置。现在我想坚持使用5。 - Anil Namde
为什么不让Fx决定使用多少线程?这是ThreadPool类的默认设置,在我的经验中它表现良好。 - Justin R.
6个回答

4

我推荐使用任务并行库/Rx(包含在.NET 4.0中,但可下载到3.5):

        var options = new ParallelOptions();
        options.MaxDegreeOfParallelism = 5;

        Parallel.ForEach(GetListOFiles(), options, (file) =>
        {
             DoStuffWithFile(file);
        });

请注意,这将使用最多5个线程,但我已经看到它使用的线程数更少。

4

1
使用setmaxthreads并不是一个推荐的做法,除非你真的知道自己在做什么。这会限制共享线程池的数量,你所使用的库可能会受到影响。 - Aryabhatta
我给了这个-1,因为通常使用它是不好的做法。 - Aryabhatta

2
将文件列表分成5个相等大小的列表。然后启动五个线程,通过ParameterizedThreadStart分别传递一个单独的较小列表。
然而,由于工作几乎完全是I/O绑定的,因此这个过程不太可能从线程中受益。

@Sam:不太确定多线程IO没有好处。有文件数据需要在内存中复制,操作系统对读取有更好的了解并可以进行优化,磁盘可以支持并行IO(RAID?)等等。当然,我们无法在实际测量之前做出结论,因此过早下结论是不妥当的。 - Aryabhatta

2

2

我通常采用以下方法:

声明一个共享整数变量来表示工作线程的数量。当将作业分配给线程(只需将作业排队到线程池中)时,增加该值。当线程完成作业时,减少该值。

确保整数值的递减或递增是原子的。

在作业调度程序中,仅在工作线程数量小于最大值时获取作业并分配给线程。否则,等待信号(由工作线程完成作业触发)。如果您想要更简单的事件,让调度程序只需执行空循环以等待。

好处在于最大值是可配置的,并且它利用了内置的线程池。编写消费者/生产者模型来解决这样一个小问题是代价高昂的。


1

使用setmaxthreads并不是一个推荐的做法,除非你确实知道自己在做什么。这会限制共享线程池,你使用的库可能会受到影响。 - Aryabhatta
我给了这个-1,因为通常使用它是不好的做法。 - Aryabhatta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接