我正在使用带有 cherrypy 服务器的 bottle 来利用多线程。据我了解,这使得每个请求都由不同的线程处理。所以给定以下代码:
from bottle import request, route
somedict = {}
@route("/read")
def read():
return somedict
@route("/write", method="POST")
def write():
somedict[request.forms.get("key")] = request.forms.get("value")
somedict 是线程安全的吗?如果运行守护线程来管理 somedict,假设它是事件 session 的字典,并且守护线程修剪过期 session 怎么办?如果不是,一个简单的锁定机制是否足够,我是否需要在读取、写入和在守护线程中使用它,或者只在守护线程中使用它?
据我所知,cherrypy 是一个真正的多线程服务器。在使用 cherrypy 作为 python 线程不是真正的线程时,我应该使用更合适的方法来实现守护进程线程吗?不过,我不想深入研究 cherrypy 环境,更喜欢在这个项目中坚持使用 bottle,所以如果它涉及从 bottle 转移/将我的应用程序迁移到 cherrypy,那么现在它并不重要。不过,我仍然想知道,因为我在他们关于线程的文档中根本看不到太多内容。
请您参考如下方法:
在您的特定示例中,是的,您执行的(单个)字典分配是线程安全的。
somedict[request.forms.get("key")] = request.forms.get("value")
但是,更一般地说,您问题的正确答案是:您将确实需要使用锁定机制。例如,如果您在处理单个请求时对 somedict 进行了多次更新,并且您需要以原子方式进行更新,则情况就是如此。
好消息是:它可能和互斥体一样简单:
from bottle import request, route
import threading
somedict = {}
somedict_lock = threading.Lock()
@route("/read")
def read():
with somedict_lock:
return somedict
@route("/write", method="POST")
def write():
with somedict_lock:
somedict[request.forms.get("key1")] = request.forms.get("value1")
somedict[request.forms.get("key2")] = request.forms.get("value2")
