2013-04-17 26 views
1

我有一些問題與goroutines。爲什麼這段代碼執行〜125ms的(注意順序執行):goroutines導致重大減速和頭痛

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)) 
} 

此代碼時需要約20秒(併發執行使用夠程):

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 
} 

使用去1.0.3上i7 720QM(4C/8T)8GB RAM linux/x86-64 也使用1.0.2構建和測試,並在同一臺機器上得到同樣的問題。

編輯:由@jnml解決下面。如果有人關心這裏的新的固定併發代碼,它是:

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 
} 
+0

我正在使用Go 1.0.3。我將恢復到1.0.2並重建它們以查看它是否對我有所幫助。 –

+0

我使用go 1.0.2構建它之後,我仍然遇到同樣的問題。 –

+0

目前還不清楚你的測試應該做什麼,但'testing.B'將會更好地測試兩段代碼之間的性能差異。 – Dustin

回答

11

IMO你的程序是不正確的。它包含一個競爭條件,因此可以從字面上做任何事情。任何時機都沒有意義。

你正在創建一個exec.Cmd,然後同時(==數據種族)從幾個夠程履行Run方法。 exec.Cmd從來沒有提到它可以重複使用多次Run - 即使是連續的。

exec.Cmd有一些狀態被exec.Command初始化,並且在執行Run後有一個不同的狀態。 IOW,執行Run方法後,狀態不再被初始化,可能不適合另一個Run

+3

爲了測試這個,我把'cmd:= exec.Command(「lessc」,「--ui-compress」,「test.less」)'移到了func lessc中,並將聲明改爲不需要指向cmd的指針。現在該程序的執行時間與順序程序相似。感謝您向我解釋這一點。 –