代码之家  ›  专栏  ›  技术社区  ›  Gnana

戈兰平行线

  •  0
  • Gnana  · 技术社区  · 9 年前

    我是刚来Golang的新手,试图理解并发和并行。我阅读了下面提到的关于并发和并行的文章。我执行了相同的程序。但没有得到相同的(字母和字符混合)输出。首先获取所有字母,然后获取字符。似乎并发正在工作,而不是并行。

    文章说添加 运行时。GOMAXPROCS(4)

    为什么我是 无法并行 ?

    系统和GO 版本1.8.2

    https://www.goinggo.net/2014/01/concurrency-goroutines-and-gomaxprocs.html

    我在这里的问题是,尽管我的系统有4个内核,并添加了运行时,但为什么我没有获得并行输出。GOMAXPROCS(4)。

    package main
    
    import (
        "fmt"
        "runtime"
        "sync"
    )
    
    func main() {
        runtime.GOMAXPROCS(2)
    
        var wg sync.WaitGroup
        wg.Add(2)
    
        fmt.Println("Starting Go Routines")
        go func() {
            defer wg.Done()
    
            for char := ‘a’; char < ‘a’+26; char++ {
                fmt.Printf("%c ", char)
            }
        }()
    
        go func() {
            defer wg.Done()
    
            for number := 1; number < 27; number++ {
                fmt.Printf("%d ", number)
            }
        }()
    
        fmt.Println("Waiting To Finish")
        wg.Wait()
    
        fmt.Println("\nTerminating Program")
    }
    

    Starting Go Routines
    Waiting To Finish
    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 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
    Terminating Program
    

    预期输出

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

    在我看来,这段代码中可能有两个问题。

     runtime.GOMAXPROCS(2)
    

    使用这一行,您只允许两个worker,但您启动了三个Go例程(Main取一个)。

    但是围棋套路的主要问题完成得太快了。正在添加

    time.Sleep(100000)
    

    将解决此问题。

    import (
        "fmt"
        "runtime"
        "sync"
    )
    
    func main() {
        runtime.GOMAXPROCS(3)
    
        var wg sync.WaitGroup
        wg.Add(2)
    
        fmt.Println("Starting Go Routines")
        go func() {
            defer wg.Done()
            for char := 'a'; char < 'a'+26; char++ {
                for i := 0; i < 10000; i++ {
                    _ = i * 2
                }
                fmt.Printf("%c ", char)
            }
        }()
    
        go func() {
            defer wg.Done()
            for number := 1; number < 27; number++ {
                for i := 0; i < 10000; i++ {
                    _ = i * 2
                }
                fmt.Printf("%d ", number)
            }
        }()
    
        fmt.Println("Waiting To Finish")
        wg.Wait()
    
        fmt.Println("\nTerminating Program")
    }
    

    在本例中,我尝试不使用sleep函数,因为它们会更改调度程序中的线程状态。结果我得到了这个。

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

    因为for循环在我上面的例子中有条件27,所以程序执行很快,无法看到并行性。我写了不同的例子,增加了条件,然后我可以看到并行输出。

    package main
    
    import (
        "fmt"
        "runtime"
        "sync"
    )
    
    var wg sync.WaitGroup
    
    func init() {
        fmt.Println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!", runtime.NumCPU())
    
    }
    func main() {
        fmt.Println(" Welcome to concurrency")
        wg.Add(2)
        go one()
        go two()
        fmt.Println("Waiting To Finish")
        wg.Wait()
        fmt.Println("\nTerminating Program")
    
    }
    
    func one() {
        for i := 0; i < 200; i++ {
            fmt.Println("one", i)
        }
        defer wg.Done()
    }
    
    func two() {
        for i := 0; i < 200; i++ {
            fmt.Println("Two:", i)
        }
        defer wg.Done()
    }
    

    2015年8月28日更新:Go 1.5被设置为使GOMAXPROCS的默认值与您机器上的CPU数量相同。我已经删除了运行时。GOMAXPROCS(4)

        3
  •  0
  •   Wanderson Silva    8 年前