多个线程之间的数据访问同步

时间:2010-08-28 18:06:29

标签: multithreading visual-c++ stl thread-safety critical-section

我正在尝试在Visual C ++中实现多线程,递归文件搜索逻辑。逻辑如下: 线程1,2将从目录位置开始,并使用搜索条件匹配目录中存在的文件。如果他们找到子目录,他们会将其添加到工作队列。一旦线程完成目录中的文件,它就会从工作队列中获取另一个目录路径。工作队列是一个STL Stack类,使用CriticalSections保护push(),pop(),top()调用。

如果堆栈在任何时候都是空的,则线程将等待一段时间再重试。此外,当所有线程都处于等待状态时,搜索被标记为完成。

这种逻辑没有任何问题,但我觉得我没有充分发挥使用线程的潜力,因为与使用单线程相比,没有显着的性能提升。我觉得工作Stack是瓶颈,但无法弄清楚如何取消锁定部分。我尝试了另一种变体,其中每个线程都有自己的堆栈,只有当本地堆栈大小超过固定数量的工作项时,才会将工作项添加到全局堆栈。如果本地Stack为空,则线程将尝试从全局队列中获取。即使有这种变化,我也没有发现明显的差异。有没有人提出改进同步逻辑的建议。

此致

2 个答案:

答案 0 :(得分:2)

我真的怀疑你的工作堆是瓶颈。磁盘只有一个磁头,一次只能读取一个数据流。只要您的线程以尽可能快的速度处理数据,您就无法做到这一点,这将对整体速度产生重大影响。

对于其他类型的任务,您的队列可能会成为一个重要的瓶颈,但对于此任务,我对此表示怀疑。请记住此处操作的时间范围。在CPU内部发生的简单操作所需的时间远小于1纳秒。从主存储器读取大约需要几十纳秒。像线程切换或同步这样的东西大约需要几百纳秒左右。磁盘驱动器上的单个磁头移动大约需要一毫秒左右(1,000,000纳秒)。

答案 1 :(得分:1)

除了@Jerry的回答,你的瓶颈就是磁盘系统。如果你有一个RAID阵列,你可能会看到使用2或3个线程的一些适度改进。

如果必须搜索多个驱动器(注意:物理驱动器,而不是单个物理驱动器上的卷),则可以为每个驱动器使用额外的线程。