商汤Golang笔试题

type DoOnePieceFunc func(piece int)

func MyFunction(ctx context.Context, workers, pieces int, doOnePiece DoOnePieceFunc)

该函数是提供给第三方的并发处理框架,其启动workers个协程并发处理用户的任务,用户任务的数据被分为总共pieces份,数据被标号为0到pieces-1,doOnePiece是用户自定义的用于处理一份数据的方法,其接收一个参数piece来指定数据的标号。MyFunction并发的执行用户任务,直到任务数据被全部处理完,或者ctx出现停止信号(ctx.Done()),每个worker同时只能处理一份数据。

注:

可以使用sync.WaitGroup
var stopCh <-chan strcut{} stopCh = ctx.Done()

package main

import (
    "fmt"
    "sync"
    "context"
)

type DoOnePieceFunc func(piece int)
 

func MyFunction(ctx context.Context, workers, pieces int, doOnePiece DoOnePieceFunc) {
    // 校验参数有效性
    if workers <= 0 || pieces <= 0 || doOnePiece == nil {
        return
    }
    if workers > pieces {
        workers = pieces
    }
 
    // 准备消费队列
    toProcess := make(chan int, pieces)
    for i := 0; i < pieces; i++ {
        toProcess <- i
    }
    close(toProcess)
 
    var stopCh <-chan struct{}
    if ctx != nil {
        stopCh = ctx.Done()
    }
 
    wg := sync.WaitGroup{}
    wg.Add(workers)
 
    for i := 0; i < workers; i++ {
        go func() {
            defer wg.Done()
            // 动态的从消费队列中获取piece
            for piece := range toProcess {
                select {
                case <-stopCh:
                    return
                default:
                    doOnePiece(piece)
                }
            }
        }()
    }
 
    wg.Wait()
}

 

posted @ 2022-03-25 19:54  Mr.peter  阅读(498)  评论(0)    收藏  举报