使用golang实现的工作池看起来比this还要近
我想在执行数据库同步(例如事务处理)的同时将我的工作人员暂停几秒钟。我不希望其他潜在的不受控制的工人更新我的同步数据。
暂停工作的最佳方法是什么?
谢谢
答案 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来防止工作?
实施起来很复杂,因为您需要发信号通知所有工人停止工作,并确保他们确实在开始工作之前已经停止积极地处理工作。反之亦然:信号重新开始。
互操作量是涉及最少代码的最简单的工作工具。我建议使用它。