Go语言的并发

Go语言的并发

原子操作

可以利用sync包中的Mutex对于资源进行加锁,从而保证资源的原子性。但其实Go官方并不推荐这种方法,更提倡用通信的方法来进行内存的共享。

不要以共享内存的方式来通信,作为替代,我们应该以通信的手段来共享内存

基于信道的通信

​ channel是在Goroutine之间进行同步的主要方法,读写通过“->”完成

​ 通过make函数进行声明

可能出现错误的操作

  • 关闭一个未初始化(nil) 的 channel 会产生 panic

  • 重复关闭同一个 channel 会产生 panic

  • 向一个已关闭的 channel 中发送消息会产生 panic

  • 从已关闭的 channel 读取消息不会产生 panic,且能读出 channel 中还未被读取的消息,若消息均已读出,则会读到类型的零值。从一个已关闭的 channel 中读取消息永远不会阻塞,并且会返回一个为 false 的 ok-idiom,可以用它来判断 channel 是否关闭

  • 关闭 channel 会产生一个广播机制,所有向 channel 读取消息的 goroutine 都会收到消息

无缓存

无论是写入还是读取channel都会阻塞,直到另外一个goroutine读取或写入这个channel

带缓存

当缓存满时,写入channel会阻塞,直到另外一个goroutine取走一个数据。

当缓存为空时,读取channel会阻塞,直到另外一个goroutine写入一个数据。

使用select同时监听多个channel

select {
    case <- ch1:
    ...
    case <- ch2:
    ...
    case ch3 <- 10;
    ...
    default:
    ...
}

如果没有定义default操作,那么当所有的channel都阻塞的时候,select也会阻塞。

这个只能监听一次消息,如果想要一直监听的话。

msgCh := make(chan struct{})
quitCh := make(chan struct{})
for {
    select {
    case <- msgCh:
        doWork()
    case <- quitCh:
        finish()
        return
}

一直循环,直到收到quit信息

经典例子

package main

import "fmt"

func generateNum() chan int {
	ch := make(chan int)
	go func() {
		for i := 2; ; i++ {
			ch <- i
		}
	}()
	return ch
}

func filter(in <-chan int, prime int) chan int {
	out := make(chan int)
	go func() {
		for {
			if i := <-in; i%prime != 0 {
				out <- i
			}
		}
	}()
	return out
}

func main() {
	ch := generateNum()
	for i := 0; i < 100; i++ {
		prime := <-ch
		fmt.Printf("%v:%v\n", i+1, prime)
		ch = filter(ch, prime)
	}
}

这个例子是书上的,但我感觉很奇怪。对于filter循环调用了100次,每次都会创建一个永远不会退出的死循环,也就是说有100个goroutine在执行完全一样的操作。感觉应该有更好的写法。

goroutine的退出

当对于一个channel执行close操作的时候,读取这个channel的地方都会接受到一个0值和一个失败标记。

func worker(channel chan bool) {
	for true {
		select {
		default:
			fmt.Println("hello")
		case <-channel:
			fmt.Println("done")
			break
		}
	}
}

func main() {
	cannel := make(chan bool)
	for i := 0; i < 10; i++ {
		go worker(cannel)
	}
	time.Sleep(time.Second)
	close(cannel)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值