我用go编写了这个小程序。关于go
关键字,我只知道当我以这种方式调用函数时,会同时执行。我没有time.Sleep()尝试执行此代码,但没有生成输出。我需要添加time.Sleep(1000)两次。一次。睡眠声明是不够的。为什么呢?
package main
import (
"fmt"
"time"
)
func doSomething(integer int) {
fmt.Println(integer)
}
func main() {
i := 1
for i <= 10 {
go doSomething(i)
i++
}
time.Sleep(1000)
time.Sleep(1000)
}
答案 0 :(得分:4)
那是因为当您使用go
调用函数时(即作为goroutine),它将在后台运行并继续执行。在这种情况下,程序在调用goroutine之后没有任何内容,所以它只是完成而你看不到输出。你为什么需要两个?嗯,你不是,只是1秒的睡眠不够长,如果你有time.Sleep(2000)
你可能得到相同的结果(虽然它&#39;不保证)。通常在使用goroutine时,需要某种阻塞语句。最简单的方法就是将一个通道传递给goroutine,然后从中接收。
由于代码的结构化,这不是最有用的示例,但这是程序的修改版本,它将阻塞直到第一个goroutine完成。由于您实际上正在调用10个goroutine,因此需要更强大的逻辑来阻塞直到它们完成,但更合理的解决方案是将循环放在gouroutine中,而不是调用10个goroutine。 https://play.golang.org/p/66g9u8Bhjj
另外,在go tour中查看这个更现实的例子; https://tour.golang.org/concurrency/2
答案 1 :(得分:1)
试试这个:
package main
import (
"fmt"
"runtime"
"time"
)
func doSomething(integer int) {
fmt.Println(integer)
}
func main() {
i := 1
for i <= 10 {
go doSomething(i)
i++
}
runtime.Gosched()
time.Sleep(10 * time.Millisecond)
}
它将以不同的方式运行。
你知道完成这个(你的)代码需要多长时间:
(考虑CPU加载100%,其他进程具有更高的优先级。)
func doSomething(integer int) {
fmt.Println(integer)
}
for i <= 10 {
go doSomething(i)
i++
}
简单回答:没有。
这取决于每个系统中的许多未知因素:
1- CPU速度和CPU核心数和CPU缓存数...
2- RAM速度和总线速度和总线矩阵(它是并发的吗?)
2- OS调度程序和OS负载和优先级
3- Golang调度器
4 CPU负载
...
我的意思是: 在并发系统和并发编程中,依靠简单的代码(或汇编)指令时序并不是一个好主意。
是的,了解Golang调度程序以及它是如何工作的很好,但是 即使你知道Golang调度程序的行为,你知道操作系统现在在做什么吗?
仅在实时操作系统中估计某些已知时间在毫秒左右的范围内。
有时甚至更好地限制并发:
这是限制并发性的一种方法:
//using chan to limit the concurrency
package main
import (
"os/exec"
"runtime"
"sync"
)
func main() {
numberOfJobs := 10
c := make(chan *exec.Cmd, numberOfJobs)
for i := 0; i < numberOfJobs; i++ {
c <- exec.Command("notepad")
}
close(c)
nCPU := runtime.NumCPU()
var wg sync.WaitGroup
for i := 0; i < nCPU; i++ {
wg.Add(1)
go func() {
for cmd := range c {
cmd.Run()
}
wg.Done()
}()
}
wg.Wait()
}
这是限制并发性的另一种方法:
//using chan to limit the concurrency
package main
import (
"os/exec"
"runtime"
"sync"
)
func main() {
n := runtime.NumCPU()
dummy := make(chan bool, n)
numberOfJobs := 10
var wg sync.WaitGroup
for i := 0; i < numberOfJobs; i++ {
cmd := exec.Command("notepad")
dummy <- true // wait here if no CPU available
wg.Add(1)
go func(cmd *exec.Cmd) {
//defer func() { <-dummy }()
cmd.Run()
wg.Done()
<-dummy
}(cmd)
}
close(dummy)
wg.Wait()
}
我希望这会有所帮助。