Multithreading 如何在围棋中安全关闭一个chan T?

Multithreading 如何在围棋中安全关闭一个chan T?,multithreading,go,synchronization,shutdown,Multithreading,Go,Synchronization,Shutdown,我正在实现一个简单的工作池算法,其中1个发送者(调度器)将作业发送给m个(工作者)go例程。为此,它使用一个通道通道为第一个空闲工作人员分配一个可用的作业: // builds the pool func NewWorkerPool(maxWorkers int) WorkerPool { pool := make(chan chan Job, maxWorkers) workers := make([]Worker, 0) return WorkerPool{

我正在实现一个简单的工作池算法,其中1个发送者(调度器)将作业发送给m个(工作者)go例程。为此,它使用一个通道通道为第一个空闲工作人员分配一个可用的作业:

// builds the pool
func NewWorkerPool(maxWorkers int) WorkerPool {
    pool := make(chan chan Job, maxWorkers)
    workers := make([]Worker, 0)
    return WorkerPool{
        WorkerPool: pool,
        Workers: workers,
        maxWorkers: maxWorkers,
        waitGroup: sync.WaitGroup{}}
}

// Starts the WorkerPool
func (p *WorkerPool) Run(queue chan Job) {
    w := p.waitGroup

    // starting n number of workers
    for i := 0; i < p.maxWorkers; i++ {
        worker := NewWorker(p.WorkerPool)
        p.Workers = append(p.Workers, worker)
        w.Add(1)
        worker.Start(&w)
    }

    go p.dispatch(queue)
}

// dispatches a job to be handled by an idle Worker of the pool
func (p *WorkerPool) dispatch(jobQueue chan Job) {
    for {
        select {
        case job := <-jobQueue:
            // a model request has been received
            go func(job Job) {
                // try to obtain a worker model channel that is available.
                // this will block until a worker is idle
                jobChannel := <-p.WorkerPool

                // dispatch the model to the worker model channel
                jobChannel <- job
            }(job)
        }
    }
}


// checks if a Worker Pool is open or closed - If we can recieve on the channel then it is NOT closed
func (p *WorkerPool) IsOpen() bool {
    _, ok := <-p.WorkerPool
    return ok
}
//打印更多?真的


即使我等待工人退出,然后调用close(p.WorkerPool),我仍然打开通道,在这种情况下缺少什么,如何相应地关闭通道

关闭通道表示不再向其发送值。这有助于向通道的接收器传达完成信息

通道中的数据仍然存在,您可能需要关闭通道,然后删除其中的所有通道,如下所示

// Stop stops the Pool and free all the channels
func (p *WorkerPool) Stop() bool {
    // stops all workers
    for _, worker := range p.Workers {
        worker.Stop()
    }
    p.waitGroup.Wait() //Wait for the goroutines to shutdown
    close(p.WorkerPool)
    for channel := range p.WorkerPool {
        fmt.Println("Freeing channel") //remove all the channels
    }
    more := p.IsOpen()
    fmt.Printf(" more? %t", more)

    return ok
}
顺便说一句,你不能使用
\ux,好吗
// stops the Pool
func (p *WorkerPool) Stop() bool {
    // stops all workers
    for _, worker := range p.Workers {
        worker.Stop()
    }
    p.waitGroup.Wait() //Wait for the goroutines to shutdown

    close(p.WorkerPool)

    more := p.IsOpen()

    fmt.Printf(" more? %t", more)

    return ok
}
// Stop stops the Pool and free all the channels
func (p *WorkerPool) Stop() bool {
    // stops all workers
    for _, worker := range p.Workers {
        worker.Stop()
    }
    p.waitGroup.Wait() //Wait for the goroutines to shutdown
    close(p.WorkerPool)
    for channel := range p.WorkerPool {
        fmt.Println("Freeing channel") //remove all the channels
    }
    more := p.IsOpen()
    fmt.Printf(" more? %t", more)

    return ok
}