Skip to content

Latest commit

 

History

History
137 lines (115 loc) · 3.2 KB

12.并发 concurrency.md

File metadata and controls

137 lines (115 loc) · 3.2 KB

并发 concurrency

-从源码解析来看, goroutine 只是由官方实现的超级 “线程池” 而已
-并发部署并行
-并发主要由切换时间片段来实现 “同时” 运行,并行则是直接利用多核实现多线程的运行,但 Go 可以设置使用核数,以发挥多核计算机的能力

import (
    "fmt"
    "time"
)

func main() {
    go Go()
    //等待两秒
    time.Sleep(2 * time.Second)
}

func Go() {
    fmt.Println("Go Go Go!!!")
}

goroutine 奉行通过通信来共享内存,而不是共享内存来通信

channel

-channelgoroutine 沟通的桥梁,大都是阻塞同步的
-通过 make 创建, close 关闭
-channel 时引用类型
-可以使用 for range 来迭代不断操作 channel
-可以设置单向或双向通道
-可以设置缓存大小,在未被填满前不会发生阻塞

func main() {
    c := make(chan bool)
    go func() {
        fmt.Println("Go Go Go!!!")
        c <- true
        close(c)
    }()
    for v := range c {
        fmt.Println(v)
    }
}

select

-可处理一个或多个 channel 的发送和接收
-同时有多个可用的 channel是按随机顺序处理
-可用空的 select 来阻塞 main 函数
-可设置超时

func main() {
    c1, c2 := make(chan int), make(chan string)
    o := make(chan bool)
    go func() {
        for {
            select {
                case v, ok := <-c1:
                    if !ok {
                        o <- true
                        break
                    }
                    fmt.Println("c1:",v)
            
                case v, ok := <-c2:
                    if !ok {
                        o <- true
                        break
                    }
                    fmt.Println("c2:",v)		
            }
        }
    }()
    c1 <- 1
    c2 <- "hi"
    c1 <- 3
    c2 <- "hello"

    close(c1)

    <-o
}

select 发送

func main() {
    c := make(chan int)
    go func() {
        for v := range c {
            fmt.Println(v)
        }
    }()

    for {
        select {
        case c <- 0:
        case c <- 1:
        }
    }

}

select 设置超时

import (
    "fmt"
    "time"
)

func main() {
    c := make(chan bool)

    select {
    case v:= <-c:
        fmt.Println(v)
    case <-time.After(3 * time.Second):
        fmt.Println("Timeout")
    }
}

课后习题

var c chan string

func Pingpang() {
    i := 0
    for {
        fmt.Println(<-c)
        c <- fmt.Sprintf("From Pingpang: Hi, #%d", i)
        i++
    }
}

func main() {
    c = make(chan string)
    go Pingpang()
    for i := 0; i < 10; i++ {
        c <- fmt.Sprintf("From Pingpang: Hello, #%d", i)
        fmt.Println(<-c)
    }
}