zoukankan      html  css  js  c++  java
  • Go基础---->go的基础学习(四)

      这里简单的介绍一下go中的关于多线程的知识。

    Go中的多线程

    一、go中简单的并发例子

    package main 
    
    import (
        "fmt"
        "time"
    )
    
    func Add(x, y int) {
        z := x + y
        fmt.Print(z, " ")
    }
    
    func main() {
        for i := 0; i < 10; i++ {
            go Add(i, i)
        }
        time.Sleep(1 * time.Second) // 睡眠一秒
        fmt.Println("hello world")
    }

    运行的结果,每次都可能不一样:

    0 6 2 12 8 4 16 10 14 18 hello world

    二、go中的并发通信

    channel是Go语言在语言级别提供的goroutine间的通信方式。channel是类型相关的。也就是说,一个channel只能传递一种类型的值,这个类型需要在声明channel时指定。

    package main 
    
    import (
        "fmt"
        "time"
    )
    
    func Count(ch chan int) {
        ch <- 1
        fmt.Println("Counting")
    }
    
    func main() {
        chs := make([]chan int, 10)
        for i := 0; i < 10; i++ {
            chs[i] = make(chan int)
            go Count(chs[i])
        }
    
        for _, ch := range(chs) {
            fmt.Print(<- ch, " ")
        }
        time.Sleep(1 * time.Second)
    }

    运行的结果,每次可能不一样:

    Counting
    1 1 1 1 1 Counting
    Counting
    Counting
    Counting
    1 1 1 1 1 Counting
    Counting
    Counting
    Counting
    Counting

    三、go中的select的使用

    Go语言直接在语言级别支持 select 关键字,用于处理异步IO问题。

    package main 
    
    import (
        "fmt"
        "time"
    )
    
    func method1(ch chan string) {
        time.Sleep(1 * time.Second)
        ch <- "one"
    }
    
    func method2(ch chan string) {
        time.Sleep(2 * time.Second)
        ch <- "two"
    }
    
    func main() {
        c1 := make(chan string)
        c2 := make(chan string)
    
        go method1(c1)
        go method2(c2)
    
        for i := 0; i < 2; i++ {
            select {
                case msg1 := <- c1:
                    fmt.Println("received1: ", msg1)
                case msg2 := <- c2:
                    fmt.Println("received2: ", msg2)
            }
        }
    }

    运行的结果如下:

    四、go中的sync.Mutex互斥锁

    package main
    
    import (
        "fmt"
        "sync"
        "time"
    )
    
    // SafeCounter 的并发使用是安全的。
    type SafeCounter struct {
        v   map[string]int
        mux sync.Mutex
    }
    
    // Inc 增加给定 key 的计数器的值。
    func (c *SafeCounter) Inc(key string) {
        c.mux.Lock()
        // Lock 之后同一时刻只有一个 goroutine 能访问 c.v
        c.v[key]++
        c.mux.Unlock()
    }
    
    // Value 返回给定 key 的计数器的当前值。
    func (c *SafeCounter) Value(key string) int {
        c.mux.Lock()
        // Lock 之后同一时刻只有一个 goroutine 能访问 c.v
        defer c.mux.Unlock()
        return c.v[key]
    }
    
    func main() {
        c := SafeCounter{v: make(map[string]int)}
        for i := 0; i < 1000; i++ {
            go c.Inc("somekey")
        }
    
        time.Sleep(time.Second)
        fmt.Println(c.Value("somekey")) // 1000
    }

    友情链接

  • 相关阅读:
    一款你不容错过的Laravel后台管理扩展包 —— Voyager
    关于后台动态模板添加内容的总结 Builder使用
    Python 解决 :NameError: name 'reload' is not defined 问题
    thinkcmf,thinksns,thinkphp,onethink三者是什么关系?
    PHP中用下划线开头的变量含义
    NetBeans 时事通讯(刊号 # 77 Oct 21, 2009)
    NetBeans 时事通讯(刊号 # 78 Oct 27, 2009)
    最受欢迎的中国 50 技术博客评选结果
    祝父亲生日快乐
    最受欢迎的中国 50 技术博客评选结果
  • 原文地址:https://www.cnblogs.com/huhx/p/baseusego4.html
Copyright © 2011-2022 走看看