Concurrency 导致严重减速和头痛的goroutines

Concurrency 导致严重减速和头痛的goroutines,concurrency,go,goroutine,Concurrency,Go,Goroutine,我对goroutines有些问题。为什么此代码在125ms内执行(注意顺序执行): 主程序包 进口( “os/exec” “时间” “fmt” ) func main(){ cmd:=exec.Command(“lessc”,“yui compress”,“test.less”) n:=2000 开始:=时间。现在() 对于i:=0;i

我对goroutines有些问题。为什么此代码在125ms内执行(注意顺序执行):

主程序包
进口(
“os/exec”
“时间”
“fmt”
)
func main(){
cmd:=exec.Command(“lessc”,“yui compress”,“test.less”)
n:=2000
开始:=时间。现在()
对于i:=0;i
当此代码大约需要20秒时(使用goroutines并发执行):

主程序包
进口(
“os/exec”
“时间”
“fmt”
)
func main(){
cmd:=exec.Command(“lessc”,“yui compress”,“test.less”)
ch:=制造(陈布尔)
n:=2000
开始:=时间。现在()
对于i:=0;i_=在我看来,你的程序不正确。它包含一个竞赛条件,因此可以做任何事情。它的任何计时都没有意义

您正在创建一个
exec.Cmd
,然后同时(=数据竞赛)从多个goroutine执行其
Run
方法。
exec.Cmd
从未提到它可以重复使用一次以上
Run
——即使是串行的


exec.Cmd
具有由
exec.Command
初始化的某些状态,并且在执行
Run
后具有不同的状态。因此,在执行
Run
方法后,该状态不再初始化,并且可能不适合另一个
Run
在您的程序不正确的情况下运行。它包含竞态条件,并且s可以做任何事情,任何时间都没有意义

您正在创建一个
exec.Cmd
,然后同时(=数据竞赛)从多个goroutine执行其
Run
方法。
exec.Cmd
从未提到它可以重复使用一次以上
Run
——即使是串行的


exec.Cmd
具有一些由
exec.Command
初始化的状态,并且在执行
Run
后有一个不同的状态。现在,在执行
Run
方法后,该状态不再初始化,可能不适合另一个
Run

我使用的是Go 1.0.3。我将恢复到1.0.2并重新构建它们,以查看是否正确对我来说有很大的不同。在我使用go 1.0.2构建它之后,我仍然有同样的问题。现在还不清楚你的测试应该做什么,但是
测试。B
将更好地测试两段代码之间的性能差异。我使用go 1.0.3。我将恢复到1.0.2并重新构建它们,看看它是否对我有影响。在我使用go 1.0.2构建它之后,我仍然有同样的问题。不清楚您的测试应该做什么,但是
testing.B
将更好地测试两段代码之间的性能差异。为了测试这一点,我移动了
cmd:=exec.Command(“lessc”、“--yui compress”、“test.less”)
转换为func-lessc,并将声明更改为不需要指向cmd的指针。该程序现在的执行时间与顺序程序的执行时间相似。感谢您向我解释。为了测试这一点,我移动了
cmd:=exec.Command(“lessc”,“--yui compress”,“test.less”)
转换为func lessc,并将声明更改为不需要指向cmd的指针。该程序现在的执行时间与顺序程序的执行时间相似。感谢您向我解释这一点。
package main

import (
  "os/exec"
  "time"
  "fmt"
)

func main() {
  cmd := exec.Command("lessc", "--yui-compress", "test.less")
  n := 2000
  start := time.Now()
  for i := 0; i < n; i++ {
    cmd.Run()
  }
  finish := time.Now()

  fmt.Printf("Program took %v to run\n", finish.Sub(start))
}
package main

import (
  "os/exec"
  "time"
  "fmt"
)

func main() {
  cmd := exec.Command("lessc", "--yui-compress", "test.less")
  ch := make(chan bool)
  n := 2000
  start := time.Now()
  for i := 0; i < n; i++ {
    go lessc(ch, cmd)
  }
  fmt.Println(n, " goroutines started.")
  for i := 0; i < n; i++ {
    _ = <-ch
  }
  finish := time.Now()

  fmt.Printf("Program took %v to run\n", finish.Sub(start))
}

func lessc(ch chan bool, c *exec.Cmd) {

  c.Run()
  ch <- true
}
package main

import (
  "os/exec"
  "time"
  "fmt"
)

func main() {
  ch := make(chan bool)
  n := 2000
  start := time.Now()
  for i := 0; i < n; i++ {
    go lessc(ch)
  }
  fmt.Println(n, " goroutines started.")
  for i := 0; i < n; i++ {
    _ = <-ch
  }
  finish := time.Now()

  fmt.Printf("Program took %v to run\n", finish.Sub(start))
}

func lessc(ch chan bool) {

  cmd := exec.Command("lessc", "--yui-compress", "test.less")
  cmd.Run()
  ch <- true
}