使用goroutines复制子目录

阿德里安

我的程序将多个文件和目录从计算机的不同部分复制到一个位置。

其中一个目录很大,因此复制大约需要20-30秒。现在,我只是制作了此方法,该方法将复制该目录以启动goroutine:

func CopySpecificDirectory(source, dest string, quit chan int) (err error) {
    files, err := os.Open(source)
    file, err := files.Readdir(0)

    if err != nil {
        fmt.Printf("Error reading directory %s: %s\n", source, err)
        return err
    }

    for _, f := range file {
        if f.IsDir() {
            copy.CopyDir(source+"\\"+f.Name(), dest+"\\"+f.Name())
        } else {
            copy.CopyFile(source+"\\"+f.Name(), dest+"\\"+f.Name())
        }
    }

    quit <- 1

    return nil
}

主要:

quit := make(chan int)
go CopySpecificDirectory(config.Location+"\\Directory", config.Destination, quit)

这只是将我的程序提高了几秒钟。在我的CopySpecificDirectory方法中(如果这是最好的方法),我希望为每个目录创建一个goroutine,如下所示:

c := make(chan int)
for _, f := range file {
    if f.IsDir() {
        go func() {
            copy.CopyDir(source+"\\"+f.Name(), dest+"\\"+f.Name())
            c <- 1
        }()
    } else {
        copy.CopyFile(source+"\\"+f.Name(), dest+"\\"+f.Name())
    }
}

使用这种方法,我不知道每个目录(<-c)要在哪里等待副本完成。
这是最好的方法吗?如果有人有其他建议,那么复制目录的最快方法是什么,我很乐意听到。

编辑:

我使用了网站上sync.WaitGroup示例的方法。

for _, f := range file {
    if f.IsDir() {
        wg.Add(1)
        go func() {
            defer wg.Done()
            copy.CopyDir(source+"\\"+f.Name(), dest+"\\"+f.Name())
        }()
    // more code

我已经声明var wg sync.WaitGroup为global,并且wg.Wait()在致电以后就直接在main中声明CopySpecificDirectory

但是CopySpecificDirectory在复制所有内容之前完成。我究竟做错了什么 ?看起来它不是在等待goroutine完成。

科斯蒂克斯

使用sync.WaitGroup()代替渠道:

  1. 创建一个等待组对象。
  2. 在生成goroutine之前,Add()先进行一遍。
  3. 当goroutine即将退出时,它将调用Done()该对象。
  4. 在您的主要(等待)代码中,调用Wait()该对象。一旦以这种方式“跟踪”的所有goroutine完成执行,此函数将返回。

请注意,您的程序是I / O绑定的,而不是CPU绑定的。可以节省一些时间,如果你的代码需要从复制文件物理上不同的设备(其他)身体不同的设备。如果您只是在同一个文件系统上混排文件,或者所有源都在同一个文件系统上,或者所有目标都在同一个文件系统上,那么您的goroutine只会在单个共享资源上竞争而不会获得太大收益(存储设备),最终结果与按顺序执行复制操作的情况没有太大不同。

举个例子,该/etc/fstab文件的手册页包含有关经典Unix系统上已安装/可安装的文件系统的信息,其中提到该OS永远不会同时检查同一物理介质上的文件系统,只能顺序检查,而不会同时检查将并行检查位于不同驱动器上的文件系统。请参阅手册页中有关该fs_passno参数的条目

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章