Pythonic 线程安全对象
在阅读了很多关于这个话题的内容并在IRC上讨论后,大家的反馈似乎是:尽量避免使用线程。抱歉重复这个问题,我的目的是想更深入地探讨这个话题,而不是接受“线程是个坏东西”的简单回答,希望能找到一个大家都能接受的解决方案。
编辑:坚决拒绝锁、死锁、锁粒度、活锁、非确定性和竞争条件这些组合而成的恶果。 --Guido van Rossum
我正在开发一个Python的网页应用程序,我想为每个用户创建一个全局对象,这个对象只能被当前用户访问。(比如请求的URI)
建议的做法是把这个对象传来传去,但我认为这样会让应用程序更难维护,而且如果我在不同地方需要同一个值(有些地方可能是第三方插件),代码看起来也不太美观。
我注意到很多流行的框架(比如Django、CherryPy、Flask)都使用Python的线程锁来解决这个问题。如果这些框架都觉得需要创建一个全局可访问的对象,那说明社区确实需要这样的东西。我也是。
把对象传来传去是“最好”的方法吗? 唯一的替代方案就是使用“坏东西”线程锁吗? 把这些信息存储在数据库或memcached中会不会更符合Python的风格呢?
提前谢谢大家!
1 个回答
5
如果你不想使用锁,那么要么就别用全局变量,要么就用线程本地存储(在一个网页应用中,你可以比较放心地认为一个请求不会跨线程)。如果能避免使用全局状态,就应该尽量避免。这样做会让多线程的实现和调试变得简单很多。
我也不同意传递对象会让应用更难维护——通常情况正好相反——全局状态会隐藏依赖关系,还需要小心同步。
当然,还有一些无锁的方法,比如软件事务内存(STM)之类的,但对于一个网页应用来说,这可能有点过于复杂了。