为什么我认为并行的程序不平行

时间:2015-07-08 14:43:44

标签: concurrency go parallel-processing

package main

import (
    "fmt"
    "runtime"
    "sync"
)

var wg sync.WaitGroup

func alphabets() {
    for char := 'a'; char < 'a'+26; char++ {
        fmt.Printf("%c ", char)
    }
    wg.Done() //decrement number of goroutines to wait for
}

func numbers() {
    for number := 1; number < 27; number++ {
        fmt.Printf("%d ", number)
    }
    wg.Done()
}

func main() {
    runtime.GOMAXPROCS(2)
    wg.Add(2) //wait for two goroutines

    fmt.Println("Starting Go Routines")
    go alphabets()
    go numbers()

    fmt.Println("\nWaiting To Finish")

    wg.Wait() //wait for the two goroutines to finish executing

    fmt.Println("\nTerminating Program")
}

我希望输出混合起来(因为没有更好的词),而是;示例输出是:

$ go run parallel_prog.go

开始Go Routines 等待完成 a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 终止程序

我错过了什么?

谢谢,

2 个答案:

答案 0 :(得分:5)

You're missing nothing. It's working. The calls aren't showing up "interlaced" (mixed up) not because they're not being parallelized, but because they're happening really fast.

You can easily add some calls to time.Sleep to see the parallelization better. By sleeping, we know 100% that printing alphabets and numbers should be interlaced.

Your program with Sleep calls to "force" interlacing

package main

import (
    "fmt"
    "sync"
    "time"
)

var wg sync.WaitGroup

func alphabets() {
    defer wg.Done()
    for char := 'a'; char < 'a'+26; char++ {
        fmt.Printf("%c ", char)
        time.Sleep(time.Second * 2)
    }
}

func numbers() {
    defer wg.Done()
    for number := 1; number < 27; number++ {
        fmt.Printf("%d ", number)
        time.Sleep(time.Second * 3)
    }    
}

func main() {
    fmt.Println("Starting Go Routines")
    wg.Add(2)
    go alphabets()
    go numbers()

    fmt.Println("\nWaiting To Finish")
    wg.Wait()
    fmt.Println("\nTerminating Program")
}

Note

You probably already know this, but setting GOMAXPROCS doesn't have any effect on whether or not this example is executed in parallel, just how many resources it consumes.

The GOMAXPROCS setting controls how many operating systems threads attempt to execute code simultaneously. For example, if GOMAXPROCS is 4, then the program will only execute code on 4 operating system threads at once, even if there are 1000 goroutines. The limit does not count threads blocked in system calls such as I/O.

Source: Go 1.5 GOMAXPROCS Default

答案 1 :(得分:3)

Are you using the Go playground by any chance? When I run your code locally, I get:

Starting Go Routines

Waiting To Finish
1 2 3 4 5 6 7 8 9 10 11 12 a 13 14 15 16 17 b 18 19 c 20 21 d 22 23 e 24 25 f 26 g h i j k l m n o p q r s t u v w x y z 
Terminating Program

The playground is deterministic in nature. Goroutines don't yield as often and don't run in multiple threads.