zoukankan      html  css  js  c++  java
  • Go基础编程实践(七)—— 并发

    同时运行多个函数

    观察常规代码和并发代码的输出顺序。

    // 常规代码,顺序执行,依次输出
    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        strN := []string{"a", "b", "c", "d"}
        for _, strV := range strN {
            time.Sleep(time.Second)
            fmt.Println(strV)
        }
    
        intN := []int{1, 2, 3, 4}
        for _, intV := range intN {
            time.Sleep(time.Second)
            fmt.Println(intV)
        }
    }
    
    // 并发代码,并发执行,无序输出
    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        go func() {
            strN := []string{"a", "b", "c", "d"}
            for _, strV := range strN {
                time.Sleep(time.Second)
                fmt.Println(strV)
            }
        }()
    
        go func() {
            intN := []int{1, 2, 3, 4}
            for _, intV := range intN {
                time.Sleep(time.Second)
                fmt.Println(intV)
            }
        }()
    
        // 防止main routine过早退出
        time.Sleep(10 * time.Second)
    }
    

    通道的关闭

    // 生产者关闭通道
    package main
    
    import (
        "time"
        "fmt"
    )
    
    func main() {
        channel := make(chan string)
        go func() {
            names := []string{"Jack", "Mike", "John", "Kitty"}
    
            for _, name := range names {
                time.Sleep(time.Second)
                // fmt.Println(name)
                channel <- name
            }
            // 发送完毕关闭通道,否则引起死锁
            close(channel)
        }()
    
        for data := range channel {
            fmt.Println(data)
        }
    }
    

    在通道中传递数据

    // 利用无缓冲通道同步传递数据
    package main
    
    import "fmt"
    
    func main(){
      nameChannel := make(chan string)
      done := make(chan string)
    
      go func(){
        names := []string {"tarik", "michael", "gopi", "jessica"}
        for _, name := range names {
          fmt.Println("Processing the first stage of: " + name)
          nameChannel <- name
        }
        close(nameChannel)
      }()
    
      go func(){
        for name := range nameChannel{
          fmt.Println("Processing the second stage of: " + name)
        }
        done <- ""
      }()
    
      <-done
    }
    
    // 利用有缓冲通道传递数据,提高性能
    package main
    
    import "fmt"
    
    func main(){
      nameChannel := make(chan string, 5)
      done := make(chan string)
    
      go func(){
        names := []string {"tarik", "michael", "gopi", "jessica"}
        for _, name := range names {
          fmt.Println("Processing the first stage of: " + name)
          nameChannel <- name
        }
        close(nameChannel)
      }()
    
      go func(){
        for name := range nameChannel{
          fmt.Println("Processing the second stage of: " + name)
        }
        done <- ""
      }()
    
      <-done
    }
    

    并发等待

    package main
    import (
        "fmt"
        "sync"
    )
    
    func main() {
        var wg sync.WaitGroup
        for i := 0; i < 10; i++ {
            // 遍历一次,增加一次计数
            wg.Add(1)
            go func(){
                fmt.Println("Hello World")
                // 执行一次,减少一次计数
                wg.Done()
            }()
        }
        // 等待计数归零,结束程序
        wg.Wait()
    }
    
    // 利用通道等待
    package main
    
    import (
        "time"
        "fmt"
    )
    
    func main() {
        channel := make(chan string)
        go func() {
            names := []string{"Jack", "Mike", "John", "Kitty"}
    
            for _, name := range names {
                time.Sleep(time.Second)
                fmt.Println(name)
                // channel <- name
            }
            // 遍历完毕向通道发送数据,告诉main routine已执行完毕
            channel <- ""
        }()
        // main routine收到数据,退出程序
        // 因为只是为了同步,不需要通道中的数据,所以将数据抛弃
        <-channel
    }
    

    选择并发结果

    package main
    
    import (
        "time"
        "fmt"
    )
    
    func main() {
        channel1 := make(chan string)
        channel2 := make(chan string)
      
        go func(){
            time.Sleep(1*time.Second)
            channel1 <- "Hello from channel1"
        }()
        go func(){
            time.Sleep(1 * time.Second)
            channel2 <- "Hello from channel2"
        }()
        var result string
        // select随机选择满足条件的case
        select {
        case result = <-channel1:
            fmt.Println(result)
        case result = <-channel2:
            fmt.Println(result)
        }
    }
    
  • 相关阅读:
    CentOS安装配置Tomcat-7
    CentOS搭建VSFTP服务器
    使用DDMS测试安卓手机APP的性能(android)
    Linux常见问题及解决方案
    数据库版本控制工具:NeXtep Designer
    身份证号码编码规则
    无网络安装mysql步骤
    HTTP协议详解
    Jenkins持续集成构建
    Gulp和Webpack对比
  • 原文地址:https://www.cnblogs.com/GaiHeiluKamei/p/11143824.html
Copyright © 2011-2022 走看看