09.2.2 创建多个Goroutine

在本小节中,您将学习如何创建任意数量的Goroutine。本节中展示的程序文件为create.go。它将分为四个部分,它将允许您创建动态数量的Goroutine,而且Goroutine的数量将以命令行参数的形式传递给程序,我们将使用flag来处理和解析命令行参数。

create.go的第一部分代码如下:

import ( 
    "flag" 
    "fmt" 
    "time" 
) 

create.go的第二部分代码如下:

func main() { 
    n := flag.Int("n", 10, "Number of goroutines") 
    flag.Parse() 
 
    count := *n 
    fmt.Printf("Going to create %d goroutines.\n", count)

上面的代码读取命令行选项n的值,该选项决定了我们将要创建的Goroutine的数量。

create.go的第三部分代码如下:

    for i := 0; i < count; i++ { 
        go func(x int) { 
            fmt.Printf("%d ", x) 
        }(i) 
    } 

for循环用于创建所需数量的Goroutine。需要再次注意的是,您不能对它们被创建和执行的顺序做出任何假设和期望。

create.go的最后一部分代码如下:

    time.Sleep(time.Second) 
    fmt.Println("\nExiting...") 
} 

为了能看到程序的输出,我们使用time.Sleep()函数来为Goroutine提供足够的时间以便能完成它们的工作。但在实际编程中,我们都希望Goroutine能尽快执行完成,所以并不需要time.Sleep()语句,后面我们将学习一种更好的技巧来保证在main()函数返回之前让所有的Goroutine执行完成。

多次执行create.go的输出如下:

$ go run create.go -n 100
Going to create 100 goroutines.
5 3 2 4 19 9 0 1 7 11 10 12 13 14 15 31 16 20 17 22 8 18 28 29 21 52 30 45 25 24 49 38 41 46 6 56 57 54 23 26 53 27 59 47 69 66 51 44 71 48 74 33 35 73 39 37 58 40 50 78 85 86 90 67 72 91 32 64 65 95 75 97 99 93 36 60 34 77 94 61 88 89 83 84 43 80 82 87 81 68 92 62 55 98 96 63 76 79 42 70
Exiting...

$ go run create.go -n 100
Going to create 100 goroutines.
2 5 3 16 6 7 8 9 1 22 10 12 13 17 11 18 15 14 19 20 31 23 26 21 29 24 30 25 37 32 36 38 35 33 45 41 43 42 40 39 34 44 48 46 47 56 53 50 0 49 55 59 58 28 54 27 60 4 57 51 52 64 61 65 72 62 63 67 69 66 74 73 71 75 89 70 76 84 85 68 79 80 93 97 83 82 99 78 88 91 92 77 81 95 94 98 87 90 96 86
Exiting...  

同样,您可以看到输出是乱序的。另外,如果你没有用time.Sleep()来保证合适的延迟,你将无法看到Goroutine的输出。

在下一节中,您将学习如何在程序结束之前让你的Goroutine有足够的时间来完成他们正在做的事情,而不再需要调用time.Sleep()。

Last updated