这段代码有竞争条件还是竞争条件只发生在协程中?如何解决这个竞争条件,最好不要使用库?
class Handler(WebSocketHandler):
listeners = {}
def open(self, sub):
self.subscriptions = [sub]
Handler.listeners.setdefault(sub, set()).add(self)
def on_close(self):
for sub in self.subscriptions:
Handler.listeners[sub].remove(self)
if not Handler.listeners[sub]:
# here in between someone might subscribe
# so we delete non empty set! which is wrong
del Handler.listeners[sub]
没有竞争条件;Tornado应用程序通常是单线程的。除非您显式地启动了任何线程,否则只有主线程在应用程序中运行。因此,您的代码不会在检查not Handler.listeners[sub]
和执行del
之间被中断。
即使你使用协程,像你这样的代码仍然没有竞争。协程不能被中断,除非它执行yield
语句。这是协程最好的特性之一。考虑一下Twisted的作者写的一篇很长的优秀文章,他认为显式异步编程(使用回调或yield
语句)优于多线程,因为在异步编程中,竞争条件更容易被发现。