【问题标题】:Execute command's and ZIP folder as async in Go在 Go 中异步执行命令和 ZIP 文件夹
【发布时间】:2018-02-08 13:51:43
【问题描述】:

我有一个程序通过cmd := exec.Command(name, args…) 执行一些命令 现在程序正在为 10 个(或更多)不同的目录执行此操作, 我的意思是我为给定路径的 10 个不同目录运行 npm install。 这个想法是 wait 执行过程将 结束 然后压缩整个文件夹(运行命令 npm install 的位置) 这里的问题是,当wait 块正在执行时,程序停止并等待(当然应该这样做......)但我想进入下一个目录并且不要等待到wait(每个目录执行)完成

建议如何以充分的方式处理它? 我的意思是在执行模块和 此外,当特定命令完成后在指定目录上运行时,无论程序何时处于进程中,都会自动对其进行压缩

这个函数针对不同的目录循环调用10次

func (n Node) Build(path string) error {
    //e.g. Run npm install which build's nodejs project
    command := exec.Command("npm", "install")
    command.Dir = n.path

 //start the execution 
  if err := command.Start(); err != nil {
    log.Printf("Failed to start cmd: %v", err)
  }



// Here I waiting to command to finish to zip the folder
if err := command.Wait(); err != nil {
   // Zip folder
}



  }

主函数如下调用它

func main() {

//Here I have loop which 

for _, dir := range dirs {

    switch dir.name {
    case "Java":
        Build(&Java{path})
    case "Go":
        Build(&Golang{path,cgoOptions},) 
    case "Node":
        Build(&Node{path})
    }
}

类似这篇文章 Using inheritance of builders in GO

【问题讨论】:

  • 性能?如果您的文件很大,避免复制将是一大优势。
  • 您有两个选择,并且您想知道哪个表现更好,所以尝试每一个,衡量每个的性能,然后比较它们。

标签: go


【解决方案1】:

您只需启动与文件夹一样多的goroutines 来并行执行程序,然后等待所有goroutine 使用wait group 完成。

例子:

import "sync"

func (n Node) Build(wg sync.WaitGroup, path string) error {
    wg.Add(1)
    defer wg.Done()

    //e.g. Run npm install which build's nodejs project
    command := exec.Command("npm", "install")
    command.Dir = n.path

    //start the execution 
    if err := command.Start(); err != nil {
        log.Printf("Failed to start cmd: %v", err)
    }

    // Here I waiting to command to finish to zip the folder
    if err := command.Wait(); err != nil {
       // Zip folder
    } 
}

func main() {
    var wg sync.WaitGroup
    node := ...
    for _, path := range dirs {
        go node.Build(wg, path)
    }

    wg.Wait()
}

UPD:一些解释。我们需要一个在主进程和所有 goroutine 之间共享的等待组对象。可以将我们的 goroutine 视为执行的逻辑线程。并且等待组作为线程安全的共享计数器变量。在我们的例子中,每个 goroutine 都是一个逻辑工作。这就是为什么我们在 thread 开始时 Add()(即增加)等待组内部计数器 1 并在退出 @ 之前通过 Done() 调用将其减少 1 987654331@ 功能。而等待组的Wait()方法只是阻塞了主进程的执行,直到内部计数器再次变为0。

【讨论】:

  • 谢谢,请您详细说明wg.Add(1) 是什么,我应该提供外部计数器吗?
猜你喜欢
  • 2021-01-29
  • 2012-05-13
  • 1970-01-01
  • 2012-11-24
  • 2016-02-03
  • 1970-01-01
  • 2013-03-22
  • 1970-01-01
  • 2015-02-26
相关资源
最近更新 更多