Java转Go语言 -13

goroutine 和 channel

并发,并行和协程
1)协程和线程没有对应关系,协程是根据一个或多个线程的可用性,映射(多路复用,执行于)在他们之上的;协程调度器在 Go 运行时很好的完成了这个工作。
2)只有 gc 编译器真正实现了协程,适当的把协程映射到操作系统线程。使用 gccgo 编译器,会为每一个协程创建操作系统线程。

协程间的信道
1)通道是为了避免使用共享变量来通信而创建的
2)通道只能传输一种类型的数据
3)通道也是引用类型
4)单纯地out<-和<-in都会阻塞,只有两个同时进行了,才能继续执行
注意
1)没有缓冲的channel,发送方会一直阻塞到接收方接收数据
2)运行时(runtime)会检查所有的协程(像本例中只有一个)是否在等待着什么东西(可从某个通道读取或者写入某个通道),这意味着程序将无法继续执行

func main() {
    out := make(chan int)
    out <- 2 //main会在这里阻塞
    go f1(out)
}
//可以运行
func main() {
    out := make(chan int)
    go f1(out) //f1会阻塞 但是main会运行 到下一步运行完 有了值之后f1会运行
    out <- 2
}
//跟第一个一样的
func main() {
    out := make(chan int)
    out <- 2 //main在这里阻塞 下面的语句不会打印出来
    fmt.Println("out")
    go f1(out)
}

总结:
1)协程是虚拟线程
2)协程之间的调度由Go Runtime来控制
runtime可以检测到死锁,过程是:检查整个程序(所有的Goroutines)是否停止?DeadLock
3)Main单独拥有一个Goroutine(称为主协程也叫做Controller)

协程的同步:关闭通道-测试阻塞的通道
在创建一个通道后使用defer语句
测试阻塞的通道:可以使用逗号,ok操作符。

使用select切换协程
很简单。

通道,超时和计时器

协程和恢复
恢复是在Panicking的协程内部的,不能被另外一个协程恢复。

新旧模型对比:任务和worker
旧模式:对任务池(共享内存)进行加锁。
新模式:使用通道,从通道得到新任务的过程中没有任何竞争。
(新旧模式没有优劣之分,合适的地方使用合适的方法)

惰性生成器实现
定义:生成器是指当被调用时返回一个序列中下一个值的函数。
返回值而不是返回整个序列,被称为惰性求值

实现Futures模式
定义:有时候在你使用某一个值之前需要先对其进行计算。这种情况下,你就可以在另一个处理器上进行该值的计算,到使用时,该值就已经计算完毕了。
适用于:计算密集型库

复用
1)使用Go的服务器通常会在协程中执行向客户端的响应,会对每一个客户端请求启动一个协程。(通常做法:客户端请求自身中包含一个通道,服务器则向这个通道发送响应)
2)卸载:通过信号通道关闭服务器
server函数现在使用select在service通道和quit通道之间做出选择

限制同时处理的请求数
使用缓冲区,缓冲区已满的时候,handle函数就会阻塞且不再处理其他请求。
使用缓冲通道(通道被用作信号量)

链式协程
注意这个链式的写法

在多核心上并行计算
分块计算嘛

并行化大量数据的计算
高效的计算方式是让每一个处理步骤作为一个协程独立工作。每一个步骤从上一步的输出通道中获得输入数据。
这个做法就不用一定等待上一步的完成。

漏桶算法
作用:突发流量可以被整形以便为网络提供一个稳定的流量。
但是通道已满的时候是不可以的,无法放到空闲通道的缓冲区,会被垃圾收集器回收。

对Go协程进行基准测试
使用通道并发访问对象
使用协程在后台顺序执行匿名函数来代替使用同步互斥锁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值