暂停工人池

时间:2018-09-05 21:11:52

标签: go worker-pool

使用golang实现的工作池看起来比this还要近

我想在执行数据库同步(例如事务处理)的同时将我的工作人员暂停几秒钟。我不希望其他潜在的不受控制的工人更新我的同步数据。

暂停工作的最佳方法是什么?

  • 关闭所有工作人员?
  • 如果暂停工作,请在工作人员中使用chan来防止工作?
  • 在处理作业之前,使用全局标志在每个工作人员中设置锁定吗?

谢谢

1 个答案:

答案 0 :(得分:4)

如果要实现数据库同步或至少将信号通知二进制文件,则可以为此目的滥用RWMutex

在工作人员从事普通工作时,请使用互斥锁的Read端,并要求在执行数据库同步操作时保持Write端。

至关重要的是,您必须确保Read仅在实际进行工作时保持为 。如果工人被阻止等待更多工作,则必须保持读取锁,因为这将使未决的编写者饿死。


如果使用此功能,我强烈建议您向代码中添加有关互斥锁的预期行为的文档,因为就读和写操作而言,这可能是不标准的。

如果您想要一个更通用的解决方案,也可以包装它并使用更好的名称从派生接口中导出不同的方法,如示例所示:

type WorkerGroupLocker struct {
    sync.RWMutex
}

func (lock *WorkerGroupLocker) LockWorker() {
    lock.RLock()
}

func (lock *WorkerGroupLocker) UnlockWorker() {
    lock.RUnlock()
}

func (lock *WorkerGroupLocker) LockBackgroundSync() {
    lock.Lock()
}

func (lock *WorkerGroupLocker) UnlockBackgroundSync() {
    lock.Unlock()
}

任何解决方案都必须解决以下一般问题:

  • 要求所有工人停止工作。
  • 确保所有工作人员已在 之前停顿下来。
  • 向工作人员发出信号,说再次继续工作是安全的。

执行此操作的替代方法包括以下内容,但我认为以下所有内容都比使用互斥锁复杂得多(因此容易产生错误):

  •   

    关闭所有工人?

    要求工作者在数据库工作进行之前停止工作将实现所需的互斥。您需要一种信号通知他们停止运行的方法,以及一种检测何时确实完成的机制。

    在任何情况下,您都可能会争辩说您需要这样做以确保在程序终止时完全关闭。但是,程序终止是致命的,因此您不需要像数据库同步工作所需的那样完全启动和停止池。

  •   

    如果暂停工作,请在工作人员中使用chan来防止工作?

    实施起来很复杂,因为您需要发信号通知所有工人停止工作,并确保他们确实在开始工作之前已经停止积极地处理工作。反之亦然:信号重新开始。

互操作量是涉及最少代码的最简单的工作工具。我建议使用它。