【问题标题】:Suspend worker pool暂停工作池
【发布时间】:2019-02-11 02:08:57
【问题描述】:

使用 golang 实现的工作池看起来比 this 更接近

我想暂停我的工作人员几秒钟,同时像事务处理一样进行数据库同步。我不希望我的同步数据被另一个潜在的不受控制的工作人员更新。

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

  • 关闭所有worker?
  • 在工作人员中使用 chan 以防止在暂停时获得工作?
  • 在处理作业之前使用全局标志在每个工作人员中设置锁定?

谢谢

【问题讨论】:

    标签: go worker-pool


    【解决方案1】:

    如果要实现数据库同步或至少向二进制文件发送信号,您可以为此目的滥用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 以防止在暂停时获得工作?

      这实施起来会很复杂,因为您需要向所有工作人员发出停止工作的信号,并确保他们确实在开始工作之前停止了积极处理工作。反过来也需要:重新开始的信号。

    对于涉及最少代码的工作,最简单的工具是互斥锁。我建议使用它。

    【讨论】:

      猜你喜欢
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-30
      • 1970-01-01
      相关资源
      最近更新 更多