暂停工作人员池

问题描述 投票:0回答:1

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

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

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

  • 关闭所有工人?
  • 在工人中使用陈可以阻止工作被暂停?
  • 在处理作业之前,使用全局标志在每个工作程序中设置锁定?

谢谢

go worker-pool
1个回答
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()
}

任何解决方案必须解决这些一般问题

  • 要求所有工人停止工作。
  • 在允许数据库工作开始之前确保所有工作人员已经停顿。
  • 发信号通知工人再次继续工作是安全的。

这样做的替代方法包括以下内容,但在我看来,下面的所有内容都比使用互斥锁要复杂得多(因此容易出错):

  • 关闭所有工人? 要求工作人员在数据库工作开始之前停止工作将实现所需的互斥。你需要一种方法来发信号通知它们停止,以及一种检测何时确实完成的机制。 无论如何,无论如何你都可以争论,以确保你在程序终止时干净地关闭。但是,程序终止是致命的,因此您无需以与此数据库同步工作所需的相同方式干净地启动和停止池。
  • 在工人中使用陈可以阻止工作被暂停? 实施起来很复杂,因为您需要发信号通知所有工人停止工作并确保他们在开始工作之前确实停止了积极处理工作。反过来也是必需的:一个信号再次开始。

涉及代码最少的工作的最简单工具是互斥锁。我推荐使用它。

© www.soinside.com 2019 - 2024. All rights reserved.