Go 并发常见讨论
并发
chan
Done 控制结束
在service开发的过程中,会有多个异步的线程同时运行,但是有时候希望对应的服务能够停止。一般都会使用close(done)
的操作
selct:
case
case <- done:
break or return
有时候这些内容会经常配合waitgroup来使用。
缓存 chan
缓存的chan主要是用来多个线程之间的任务或者数据队列
timer chan
Lock 与 condition
Lock的使用非常简单,在多线程应用中,进行并发控制。
condition的主要使用就是
Wait()
Signal()
Broadcast()
waitGroup
wg的主要使用就是为了控制多个子线程运行的过程中,子线程退出以后才可以退出。
混合使用案例
问题描述:开始的时候需要完成N个tasks,其中每一个task的id是固定的。但是做task的worker是未知的,每次提交一个task的时候就需要一个独占的worker,执行完任务以后就又需要把worker还回去。实现一个这样的模型来完成功能(只有所有任务都正确的结束才能够退出function)
需求描述
-
任务数目固定
-
如果可用worker较多,尽可能的并发提交任务(因为worker类似于一个资源队列,每次都需要从队列中取出来一个元素)
-
并发提交任务(任务成功,返回资源;任务失败进行重做);为了考虑到所有异步task全部处理结束以后,才可以退出整个方法。go中需要使用waitGroup,java中需要使用countDown
code 实现需求
chan 与 buffer混合
有些资源需要使用和释放,所以使用一个buffer chan的操作会好一点。
使用的时候从buffer chan中获取,使用完以后放入buffer chan中。如果buffer 没有或者满了就new一个新的。
// 初始化一个buffer大小的chan list
var freeList = make(chan *Buffer, 100)
var serverChan = make(chan *Buffer)
func client() {
for {
var b *Buffer
// Grab a buffer if available; allocate if not.
select {
// 使用时候从buffer list中拿去,如果没有就default
case b = <-freeList:
// Got one; nothing more to do.
default:
// None free, so allocate a new one.
b = new(Buffer)
}
load(b) // Read next message from the net.
serverChan <- b // Send to server.
}
}
func server() {
for {
b := <-serverChan // Wait for work.
process(b)
// Reuse buffer if there's room.
// 使用完毕的buffer
select {
// 如果能够返回给 buffer就结束
case freeList <- b:
// Buffer on free list; nothing more to do.
default:
// 不能就释放
// Free list full, just carry on.
}
}
}
网友评论