go并发

go并发

go语言天生支持并发!!!

通过goroutine关键字来开启!

goroutine轻量级线程,goroutine运行时管理!!!

同一个程序中的goroutine共享同一个地址空间!!!

语法格式:

  go 函数名(参数列表)

示例:

package mian

import (
    "fmt"
    "time"
)

func sayhello(s string)  {
    for i :=0;i<10;i++{
        time.Sleep(100*time.Microsecond)
        fmt.Println(s)
    }
}

func main()  {
    go sayhello("hello")
    sayhello("world")
}

通道(channel)

channel:用来传递数据的一个数据结构!

两个goroutine之间通过传递一个指定的类型值来进行同步和通讯!!!

操作符: <-

ch <- v    // 把 v 发送到通道 ch
v := <-ch  // 从 ch 接收数据
           // 并把值赋给 v

申明一个通道:

ch :=make(chan int)

package main

import "fmt"

func sum(s []int,c chan int){
    sum :=0
    for _,v := range s{
        fmt.Println(v)
            sum += v
    }
    c <- sum
}



func main() {
    s := []int{7,2,8,-9,4,0}

    c := make(chan int)
    go sum(s[:len(s)/2],c)
    go sum(s[:len(s)/2],c)
    x,y := <-c,<-c
    fmt.Println(x,y,x+y)
}

通道缓冲区

设置通道缓冲区的大小,为可选参数

ch :=make(chan int,2)

func main() {
    ch := make(chan int, 2)
    ch <- 200000000
    ch <- 3000000000000
    fmt.Println(<-ch)
    fmt.Println(<-ch)
}

遍历通道和关闭通道

支持range关键字遍历和读取,类似于 切片和数组!!!

遵循先进先出!!!

当通道接收不了数据后,就可以是有close()函数来关闭!!!

使用cap()查看通道的大小!!!

func main() {
    ch := make(chan int, 10)
    for i := 0;i<cap(ch);i++{
        ch <- i
    }
    close(ch)
    for i := range ch{
        fmt.Println(i)
    }

}

延伸

在goroutine的时候主函数先退出,利用chan实现等待goroutine结束后,再退出主函数!!!

闭通道并不会丢失里面的数据,只是让读取通道数据的时候不会读完之后一直阻塞等待新数据写入!!!

有没有缓冲区的区别:

  不带缓冲区的通道在向通道发送值时,必须及时接收,且必须一次接收完成。

而带缓冲区的通道则会以缓冲区满而阻塞,直到先塞发送到通道的值被从通道中接收才可以继续往通道传值。就像往水管里推小钢珠一样,如果钢珠塞满没有从另一头放出,那么这一头就没法再往里塞,是一个道理。

 

 

 

 

 

posted @ 2019-11-25 12:20  qijunL  阅读(123)  评论(0)    收藏  举报