正确的方法为工作人员goroutine排队项目?

时间:2017-11-17 01:44:33

标签: go race-condition channel

我正在编写一个应用程序,允许用户上传文件并将其排队等待处理。我的方法是创建一个用于处理上传文件的goroutine,并使用一个通道来表示新文件已准备好进行处理。

基本上,处理goroutine执行此操作:

for {
    while itemForProcessing() {
        processNextItem()
    }
    select {
    case <-signalChan:
    case <-stopChan:
        return
    }
}

用于表示新项目已准备好进行处理的代码如下所示:

select {
case signalChan <- true:
default:
}

请注意,这是频道上的非阻止发送。

有三种可能的情况:

  • 处理goroutine位于select{}块中 - 第一个案例运行且下一个项目已处理
  • 处理goroutine正在执行processNextItem() - 由于循环条件为processNextItem()
  • ,因此true返回后将处理下一个项目
  • 处理goroutine退出循环但尚未进入select{}

最后一个场景会导致问题。非阻塞发送不会在通道上发送任何内容,并且goroutine将在select{}块中等待,直到发生其他情况。

我该如何避免这个问题?我不能使用阻塞发送,因为处理goroutine可能正在运行processNextItem(),这将导致发送阻塞很长一段时间。

1 个答案:

答案 0 :(得分:2)

为避免信号丢失,请使用容量为1的频道。