• 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
    }

    友情链接

  • 相关阅读:
    弹出窗口js
    c 中的字符串的一个问题
    2012年4月29日
    iOS开发之详解剪贴板 CocoaChina 苹果开发中文站 最热的iPhone开发社区 最热的苹果开发社区 最热的iPad开发社区 (2)
    自定义标签栏 ios
    使用委托在对象间传递信息
    NSNotificationCenter消息注册与撤销
    Xcode_免证书开发调试_ipad_程序开发
    文件签名
    iOS获取当前系统的相关信息 博客频道 CSDN.NET (3)
  • 原文地址:https://www.cnblogs.com/huhx/p/baseusego4.html
Copyright © 2020-2023  润新知