我正在使用亚马逊的SES从我的Python Google App Engine应用程序发送电子邮件。我想保存SES连接,而不是为我发送的每封电子邮件创建它。
对于多线程应用来说,这是一种合理的方法吗?:
SES = None
def send_email_AWS(sender, to_addresses, subject, body):
global SES
if not SES:
SES = SESConnection(aws_key, aws_secret)
[other code for sending the email]
我对什么是线程安全和什么不是什么没有很好的理解。
答案 0 :(得分:3)
以下示例可以帮助您:http://blog.notdot.net/2011/10/Migrating-to-Python-2-7-part-1-Threadsafe
class SesConnection(object):
_SES = None
_aws_key = ....
_aws_secret = ....
_ses_lock = threading.Lock()
@classmethod
def get_ses(cls):
with cls._ses_lock:
if not cls._SES:
cls._SES = SESConnection(cls._aws_key, cls._aws_secret) # or put the code here
return cls._SES
或使用webapp2 app注册表:http://webapp-improved.appspot.com/guide/app.html#registry
答案 1 :(得分:1)
从您的示例中您没有任何问题如果您只是正在阅读,就像它是一个常量一样。 您的公共变量SES不是线程安全的。这意味着,例如,如果有许多用户写入该全局,那么您将始终读取发生的最后一次写入而不是每个实例。
线程是人的图像。不要以为您的全局变量是公共WC。线程安全有门(锁)。如果我们没有锁定,那么每个人都会尝试做他的工作而另一个人在里面。
对于你的例子,我看到:
SES = NONE
这意味着您的应用的每个实例都将重置SES全局变量。不是一件好事。
global SES
if not SES:
然后第一个请求会再次设置它。但它不安全,因为同时其他一些请求可能会覆盖它。如果那不是问题,那就好了。 你需要的是每个请求处理程序在本地创建它,如果这是为了线程安全。
@voscausa的回答显示了一个很好的实现示例。看看