首页 > 其他 > 详细

Golang并发编程之channel

时间:2020-02-23 09:06:25      阅读:68      评论:0      收藏:0      [点我收藏+]

channel

单纯将函数实现并发是没有任何意义的,函数与函数之间需要交换数据才能够体现并发执行函数的意义。
虽然可以使用共享内存进行数据交换,但是共享内存在不同的goroutine中容易发生竞态情况。为了保证数据交换的正确性,必须使用互斥量对内存进行加锁,这种做法肯定会造成性能影响。

Go语言的并发模型是CSP,提倡通过通信共享内存而不是通过共享内存而实现通信。

如果说goroutine是Go程序并发的执行体,channel就是他们之间的连接。channel是可以让一个goroutine发送特定值到另一个goroutine的通信机制。

Go语言中的通道(channel)是一种特殊的类型,通道像一个传送带或者队列,总是遵循先入先出(FIFO)的规则,保证收发数据的顺序。每一个通道都是一个具体类型的导管,也就是声明channel的时候需要为其制定元素类型。

channel类型

声明通道类型的格式如下:

var 变量 chan 元素类型

举几个例子

var a1 chan int   // 声明一个int类型的chan
var a2 chan str   // 声明一个str类型的chan
var a3 chan []int // 声明一个int slice的chan

创建channel

channel是一个引用类型,往channel里写入数据相当于是拿到其内存地址操作,必须使用make函数初始化(通道类型的控制是nil)

package main

import "fmt"

var a chan int

func main(){
    a = make(chan int,15) // 通道初始化(带缓冲区)
    fmt.Println(a)     // 0xc000098000

}

channel操作

通道有发送(send)、接收(receive)和关闭(close)三种操作,发送和接收都是用<-符号。
先定义一个通道

b := make(chan int,15)

发送
将一个值发送到通道中

b <- 20 // 把20发送到b中

接收

x := <- b // 从b中接收值并赋值给变量x
<-b       // 从b中接收值      

关闭
通过调用内置的close函数来关闭通道

close(b)

关于关闭通道需要注意的是,只有在通知接收方goroutine所有的数据都是发送完毕的时候才需要关闭通道。通道是可以被垃圾回收机制回收的,它和关闭文件机制是不一样的,在结束操作之后关闭文件时必须要做的,但是关闭通道不是必须的。

channel练习题

需求:
1.启动一个goroutine,生成100个数发送到ch1
2.启动一个goroutine,从ch1中取值,计算其平方放到ch2中
3.在main中,从ch2取值打印出来

代码:

package main

import (
    "fmt"
    "sync"
)

var wg sync.WaitGroup

func f1(ch1 chan int){
    defer wg.Done()
    for i:=0;i<100;i++{
        ch1 <- i
    }
    close(ch1)
}

func f2(ch1,ch2 chan int){
    defer wg.Done()
    for {
        x,ok := <- ch1
        if !ok{
            break
        }
        ch2 <- x * x
    }
    close(ch2)
}

func main(){
    a := make(chan int,100)
    b := make(chan int,100)
    wg.Add(2)
    go f1(a)
    go f2(a,b)
    wg.Wait()
    for ret := range b {
        fmt.Println(ret)
    }
}

Golang并发编程之channel

原文:https://www.cnblogs.com/jasonminghao/p/12348281.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!