代码之家  ›  专栏  ›  技术社区  ›  ivymike

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

  •  1
  • ivymike  · 技术社区  · 15 年前

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

    如果堆栈在任何点上都为空,则线程将等待一分钟的时间,然后重试。此外,当所有线程都处于等待状态时,搜索将标记为完成。

    这个逻辑可以毫无问题地工作,但是我觉得我没有获得使用线程的全部潜力,因为与使用单线程相比,没有显著的性能提升。我觉得工作堆是瓶颈,但不知道如何去掉锁定部分。我尝试了另一种变体,其中每个线程都有自己的堆栈,只有当本地堆栈大小与固定数量的工作项交叉时,才会向全局堆栈添加工作项。如果本地堆栈为空,线程将尝试从全局队列提取。即使有这种变化,我也没有发现明显的区别。是否有人对改进同步逻辑有任何建议?

    当做,

    2 回复  |  直到 15 年前
        1
  •  2
  •   Jerry Coffin    15 年前

    我真的怀疑你的工作是瓶颈。磁盘只有一个磁头,一次只能读取一个数据流。只要您的线程处理数据的速度达到磁盘所能提供的速度,那么您就没有其他方法可以做到这一点,这将对总体速度产生任何显著的影响。

    对于其他类型的任务,您的队列可能会成为一个重要的瓶颈,但对于这个任务,我表示怀疑。记住这里操作的时间尺度。一个简单的操作发生在一个中央处理器内部所需的时间远远少于一纳秒。从主存储器中读取的数据大约需要几十纳秒。像线程切换或同步之类的东西大约需要几百纳秒。磁盘驱动器上的单磁头移动大约需要一毫秒(1000000纳秒)。

        2
  •  1
  •   Jerry Coffin    15 年前

    除了@jerry的答案,您的瓶颈是磁盘系统。如果您有一个RAID阵列,您可能会看到从使用2或3个线程中得到一些适度的改进。

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