go 并发编程

概念

  • 协程与传统的系统级线程和进程相比,协程的最大优势在于其“轻量级”,可以轻松创建上百万个而不会导致系统资源衰竭,而线程和进程通常最多也不能超过1万个。这也是协程也叫轻量级线程的原因。多数语言不支持携程,而是通过库的方式支持,这样如果调用同一个io如本地文件读写都会阻塞其他并发执行轻量级线程。
  • go在语言级别支持协程,叫goroutine。
  • go 关键词后面的语句会以一个新的线程去运行。

goroutine

func main() {
    go fmt.Println("Hello from another goroutine”)// 线程
    fmt.Println("Hello from main goroutine")

    // 至此,程序运行结束,
    // 所有活跃的goroutine被杀死
}
// 函数Publish在给定时间过期后打印text字符串到标准输出
// 该函数并不会阻塞而是立即返回
func Publish(text string, delay time.Duration) {
    go func() {
        time.Sleep(delay)
        fmt.Println("BREAKING NEWS:", text)
    }()    // 注意这里的括号。必须调用匿名函数
}
func main() {
    Publish("A goroutine starts a new thread of execution.", 5*time.Second)
    fmt.Println("Let’s hope the news will published before I leave.")
    // 等待发布新闻
    time.Sleep(10 * time.Second)
    fmt.Println("Ten seconds later: I’m leaving now.")
}



输出:
Let’s hope the news will published before I leave.
BREAKING NEWS: A goroutine starts a new thread of execution.
Ten seconds later: I’m leaving now.

channel(通道)

  • channel是Go语言在语言级别提供的goroutine间的通信方式。

  • channel是类型相关的。也就是说,一个channel只能传递一种类型的值,这个类型需要在声明channel时指定。

  • 声明格式:var chanName chan ElementType

通道发送数据的格式

通道变量 <- 值

通道接收数据
  • 通道接收同样使用<-操作符
  • 阻塞接收数据,阻塞模式接收数据时,将接收变量作为<-操作符的左值 data := <-ch
  • 非阻塞接收数据,data, ok := <-ch data:表示接收到的数据。 ok:表示是否接收到数据。
  • 接收任意数据,忽略接收的数据<-ch
func sum(s []int, c chan int) {
        sum := 0
        for _, v := range s {
                sum += v
        }
        c <- sum // 把 sum 发送到通道 c
}
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 // 从通道 c 中接收
        fmt.Println(x, y, x+y)
}
输出结果为:
-5 17 12
注意:默认情况下,通道是不带缓冲区的。发送端发送数据,同时必须又接收端相应的接收数据。
通道缓冲区

道可以设置缓冲区,通过 make 的第二个参数指定缓冲区大小 :ch := make(chan int, 100)

func main() {
    // 这里我们定义了一个可以存储整数类型的带缓冲通道
        // 缓冲区大小为2
        ch := make(chan int, 2)
        // 因为 ch 是带缓冲的通道,我们可以同时发送两个数据
        // 而不用立刻需要去同步读取数据
        ch <- 1
        ch <- 2
        // 获取这两个数据
        fmt.Println(<-ch)
        fmt.Println(<-ch)
}

输出结果为:
1
2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值