2015-11-04 49 views
1

我已經設置了runtime.GOMAXPROCS(2),但是這個程序在輸出一些數字時仍然掛起。我可以看到這個程序使用的高CPU(超過100%),但我不明白爲什麼for循環goroutine可以使我的程序無法正常工作。GOMAXPROCS已經是2,但程序仍然掛起

在linux/amd64上版本是1.4.2,我的電腦有4個CPU。

這裏是代碼:

package main 

import "fmt" 
import "runtime" 
import "time" 

func forever() { 
    for { 
    } 
} 

func show() { 
    for number := 1; number < 999999; number++ { 
     time.Sleep(1000) 
     fmt.Println(number) 
    } 
} 

func main() { 
    runtime.GOMAXPROCS(2) 
    go show() 
    go forever() 
    for { 
     time.Sleep(1000) 
    } 
} 

回答

2

沒有必要永遠有一個繁忙的循環,什麼也不做,除了燒傷的CPU時間。它不僅會佔用整個操作系統線程,而且會根據協程來調度,並且會干擾運行時的goroutine。例如,在Go1.5上,這通常會阻止GC的停止世界階段(您可以通過設置GOGC=off來進行測試)。

爲了使這個程序運行,你可以插入一個調度點的for循環(或更好,但擺脫它完全):

func forever() { 
    for { 
     runtime.Gosched() 
    } 
} 
+0

是否time.Sleep()不阻止並重新安排? – captncraig

+0

我期望永遠消耗一個操作系統線程,主要和顯示將爭取剩下的一個。也許事實上並非如此? – captncraig

+0

@ captncraig:time.Sleep是一個調度點,但如果睡眠太短,Gosched效率會更高,因爲它更少。 – JimB

0

從代碼,它看起來像你想打印在for循環中進入例程。在這種情況下,爲什麼不使用通道來指示何時使用for循環完成例程,並相應地退出主函數。像這樣的東西

package main 

import "fmt" 
import "runtime" 
import "time" 


func show(result chan bool) { 
    for number := 1; number < 999999; number++ { 
     time.Sleep(1000) 
     fmt.Println(number) 
    } 
    result <- true 
} 

func main() { 
    runtime.GOMAXPROCS(2) 
    result := make(chan bool) 
    go show(result) 
    <- result 
} 
+0

感謝您的回答,但您的答案不是我想要的。我只想知道,當有2個內核線程時,在這個程序中goroutine不能工作。 – QthCN

相關問題