使用看起来比这更接近的工作池的 golang 实现
我想暂停我的工作人员几秒钟,同时像事务处理一样进行数据库同步。我不希望我的同步数据被另一个潜在的不受控制的工作人员更新。
暂停工作的最佳方法是什么?
- 关闭所有工人?
- 如果被暂停,请在工人中使用 chan 以防止获得工作?
- 在处理工作之前使用全局标志在每个工作人员中设置锁定?
谢谢
使用看起来比这更接近的工作池的 golang 实现
我想暂停我的工作人员几秒钟,同时像事务处理一样进行数据库同步。我不希望我的同步数据被另一个潜在的不受控制的工作人员更新。
暂停工作的最佳方法是什么?
谢谢
如果要实现数据库同步或至少向二进制文件发送信号,则可以RWMutex
为此目的滥用 an。
在 worker 中做普通工作时使用Read
mutex 的边,并要求在 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 以防止获得工作?
这实施起来会很复杂,因为您需要向所有工作人员发出停止工作的信号,并确保他们在开始工作之前确实停止了积极处理工作。反过来也需要:重新开始的信号。
涉及最少代码的工作的最简单工具是互斥锁。我建议使用它。