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
}

友情链接

原文地址:https://www.cnblogs.com/huhx/p/baseusego4.html