1

Amazon の 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]

何がスレッドセーフで何がそうでないのかよくわかりません。

4

2 に答える 2

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アプリレジストリを使用します:http ://webapp-improved.appspot.com/guide/app.html#registry

于 2012-12-15T20:50:13.850 に答える
1

あなたの例から、それが定数であるかのようにそれを 読んでいるだけなら、問題はありません。パブリック変数SESはスレッドセーフではありません。つまり、たとえば、そのグローバルに書き込みを行うユーザーが多かった場合、インスタンスごとではなく、最後に発生した書き込みを常に読み取ることになります。

スレッドは人であるというイメージ。グローバル変数がパブリックWCであるとは想像できません。スレッドセーフはドア(ロック)を備えています。私たちがロックを持っていなかったら、他の人が中にいる間に誰もが彼の仕事をしようとしているでしょう。

あなたの例のために私は見る:

SES = NONE 

これは、アプリの各インスタンスがSESグローバル変数をリセットすることを意味します。良くないことです。

global SES
    if not SES:

次に、最初のリクエストで再び何かに設定されます。しかし、同時に他のリクエストがそれをオーバーライドする可能性があるため、安全ではありません。それが問題でなければ、大丈夫です。スレッドセーフを目的としている場合は、リクエストハンドラごとにローカルで作成する必要があります。

@voscausaによる回答は、優れた実装例を示しています。見てみな

于 2012-12-23T19:12:52.350 に答える