sam*_*mol 7 concurrency multithreading semaphore thread-safety go
Go 中的信号量是通过通道实现的:
一个例子是这样的:https : //sites.google.com/site/gopatterns/concurrency/semaphores
语境:
我们有几百台服务器,并且有我们想要限制访问的共享资源。因此,对于给定的资源,我们希望使用信号量将访问限制为这些服务器只能同时访问 5 个。为了做到这一点,我们计划使用锁服务器。当一台机器访问资源时,它首先会向锁服务器注册它正在通过密钥访问资源。然后当它完成时,它会向锁服务器发送另一个请求,说它完成并释放信号量。这确保我们将对这些资源的访问限制为最大数量的并发访问。
问题:如果出现问题,想要优雅地处理这个问题。
问题:
你如何在信号量上实现超时?
例子:
假设我的信号量大小为 5。同时有 10 个进程试图获取信号量中的锁,因此在这种情况下,只有 5 个进程会获取它。
有时,进程会在没有响应的情况下死亡(真正的原因解释起来有点复杂,但基本上有时进程可能无法解锁它),因此会导致问题,因为信号量中的空间现在被永久锁定。
所以我想暂停一下。这里有一些问题:
这些过程将在 2 秒到 60 分钟之间的任何时间运行。
我们有一些竞争条件,因为如果它超时然后进程试图解锁它,那么我们已经解锁了信号量两次而不是一次。反之亦然,我们先解锁,然后超时。
我如何采用上面发布的建议模式并将其转换为具有超时的线程安全信号量?
弄清楚你想要完成什么有点困难,但据我所知,你试图让并发 goroutine 访问共享资源,并在出现问题时优雅地处理它。我对如何处理这个问题有一些建议。
1)使用同步包中的WaitGroup:http://golang.org/pkg/sync/#example_WaitGroup
使用此策略,您基本上可以在每次调用新 goroutine 之前添加一个计数器,并使用 defer 来确保它从计数器中删除(因此,无论它超时还是由于其他原因返回,它仍然会从计数器中删除)。然后,您使用一个wg.Wait()命令来确保它不会再继续下去,直到所有 go 例程都返回为止。这是一个示例:http://play.golang.org/p/wnm24TcBZg请注意,如果没有它wg.Wait(),它不会等待 go 例程完成,然后再从 main 返回并终止。
2)使用 time.Ticker 自动超时:http://golang.org/pkg/time/#Ticker
这种方法基本上会设置一个计时器,该计时器将按照设定的时间间隔触发。您可以使用此计时器来控制基于时间的事件。基本上,这必须在 for 循环中运行,等待通道被输入一个刻度,如本例所示: http: //play.golang.org/p/IHeqmiFBSS
同样,不完全确定您要实现的目标,但您可以考虑将这两种方法结合起来,这样,如果您的进程超时并处于循环中,则自动收报机将捕获它并在设定的时间后返回并调用 deferwg.Done()函数,以便等待它的代码部分继续运行。希望这至少有一点帮助。