Go 并发常见讨论

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)

需求描述

  1. 任务数目固定

  2. 如果可用worker较多,尽可能的并发提交任务(因为worker类似于一个资源队列,每次都需要从队列中取出来一个元素)

  3. 并发提交任务(任务成功,返回资源;任务失败进行重做);为了考虑到所有异步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.
        }
    }
}

你可能感兴趣的:(Go 并发常见讨论)