查看完整版本: [-- 多线程拷贝整个目录速度能更快吗?原理是什么? --]

QTCN开发网 -> Qt基础编程 -> 多线程拷贝整个目录速度能更快吗?原理是什么? [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

stlcours 2015-08-03 23:23

多线程拷贝整个目录速度能更快吗?原理是什么?

最近用QT做了一个小功能,就是拷贝整个目录,我已经把此函数写在线程里运行,大致代码如下:

void MyThread::CopyFolder(QString path) {
    if (!QDir(path).exists()) return;
    // 过滤器
    QStringList filters;
    QDirIterator dir_iterator(path,
        filters, // hang 如果不想加入过滤器,定义一个空过滤器即可
        //QDir::DirsFirst | NoFilter,
        // QDir::AllDirs,
        // QDir::DirsFirst | QDir::NoDotAndDotDot | QDir::AllEntries | QDir::CaseSensitive
        QDir::NoDotAndDotDot | QDir::AllEntries | QDir::Hidden | QDir::System, // 默认传输隐藏文件
        QDirIterator::Subdirectories);

    while(dir_iterator.hasNext())
    {
        dir_iterator.next();

        // 跳过少部分不想要的文件
        const QFileInfo file_info = dir_iterator.fileInfo();

        // 真正拷贝
        if (file_info.isFile()) {
           // 拷贝文件,主要是使用QFile::copy函数
        }
        else if (file_info.isDir()) {
          // 创建目录,主要是使用QDir::mkdir函数
        }
    }
}
----------------------------------------------------------------
据我所知,多线程的出现,主要是为了利用CPU空闲时间,因为各种外设的速度相当于CPU来说太慢。但是如果我把这个目录拷贝函数写成多线程的话(假设我先执行分析目录内所有文件信息,并能合理分配给多个线程去拷贝这些文件),会速度更快还是更慢?
表面上各个线程可以不间断使用CPU的资源进行拷贝,可是磁盘的磁头只有一个呀!磁头正在一个地方写文件,忽然接到指令要求移到另一个地方读文件,但是这样磁头会疲于奔命,因为它的移动速度远远赶不上CPU的命令,这样岂不是效率更低?
除非现在的硬盘有上千个磁头,可多处同时读写硬盘(是真的同时,不是多线程伪装的),这样才会效率很高。

那么问题来了:
1. 多线程拷贝整个目录速度是否更快?原理是什么?
2. 现在的硬盘有多少个磁头,可同时读写硬盘吗?

提示:
王艳平老师写的《Windows程序设计》第92页,有一个“多线程文件搜索器”,书在这里下载?
https://book-cs.googlecode.com/svn/trunk/windows/Windows%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E7%8E%8B%E8%89%B3%E5%B9%B3.pdf
从这个例子来看,多线程搜索确实应该更快才对,但是这是为什么呢?

彩阳 2015-08-04 00:34
机械硬盘才会出现IO性能瓶颈,固态硬盘不会;
此外,多线程IO如果运用的是多核CPU的话,效率会高一些,但是还是和IO相关。要知道IO是效率比较低的操作。
可以看看有关多线程IO的相关文章:http://blog.csdn.net/hmsiwtv/article/details/24598305
也可以看看并行程序相关的文章:http://www.opengpu.org/forum.php?mod=viewthread&tid=16490

dosmlp 2015-08-04 08:53
如果是机械硬盘并不会提高效率,即使程序性能提高了,到了硬盘这个物理层还是要排队读写

zgfree 2015-08-04 10:56
应该会快一些,系统会先写缓存,再一次写磁盘。

stlcours 2015-08-04 15:45
彩阳:机械硬盘才会出现IO性能瓶颈,固态硬盘不会;
此外,多线程IO如果运用的是多核CPU的话,效率会高一些,但是还是和IO相关。要知道IO是效率比较低的操作。
可以看看有关多线程IO的相关文章:http://blog.csdn.net/hmsiwtv/article/details/24598305
也可以看看并行程序相关的文章:h .. (2015-08-04 00:34) 

大多数人仍然都是用机械硬盘啊,这点必须考虑到。正如你推荐的文章里写道:
>>唯一需要考虑的,单线程异步IO可能对多核CPU的利用不如传统的多线程充分。
拷贝这个事情,当然是CPU不密集的,主要都是IO的操作。所以多线程拷贝其实没有优势,甚至还有损失。尽管楼下说硬盘有缓存,可是硬盘的缓存都是很小的,通常都只有32M而已,无法抵消IO疲于奔命的劣势。

并行编程的原理我都懂,但绝大多数都是为了CPU密集的情况,或者就是让客户机及时得到服务器的相应,但我这里不是这种情况。

stlcours 2015-08-04 15:47
dosmlp:如果是机械硬盘并不会提高效率,即使程序性能提高了,到了硬盘这个物理层还是要排队读写[表情] 的 (2015-08-04 08:53) 

当然是机械硬盘,因为这是大多数客户机的情况,不是服务器应用。其实我觉得不仅效率不会提高,而且还会降低,不是吗?

stlcours 2015-08-04 15:48
zgfree:应该会快一些,系统会先写缓存,再一次写磁盘。 (2015-08-04 10:56) 

硬盘的缓存都是很小的,通常都只有32M而已,我认为无法抵消IO疲于奔命的劣势。

zgfree 2015-08-05 11:01
stlcours:硬盘的缓存都是很小的,通常都只有32M而已,我认为无法抵消IO疲于奔命的劣势。 (2015-08-04 15:48) 

做过测试吗?
一次写一块(片)的速度快,还是每次写一点的速度快。写数据库大家都知道,一次插入一批速度比来一条数据插入一条的速度总体速度快很多很多。

stlcours 2015-08-05 15:49
zgfree:做过测试吗?
一次写一块(片)的速度快,还是每次写一点的速度快。写数据库大家都知道,一次插入一批速度比来一条数据插入一条的速度总体速度快很多很多。 (2015-08-05 11:01) 

还没做测试。这东西做测试不直观,因为你看不到硬盘到底是什么样的(DB则可以观测),硬盘的缓存内容和状态如何等等,实在很难观察,另外OS的状态对硬盘影响也比较大。

其实我之所以在这里问这个问题就是因为写代码很麻烦,做测试很麻烦,但是如果大家一致认为多线程更快,我才会去写这个东西,否则就没有必要~

lwei24 2021-07-07 20:13
楼主,请问多线程拷贝时,碰到线程执行到copy这个接口函数时,主界面卡顿,怎么办呢?


查看完整版本: [-- 多线程拷贝整个目录速度能更快吗?原理是什么? --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled