私は現在、Python での Web アプリケーションの WSGI 仕様に精通しています。各リクエストの一意性を観察するために、現在スレッド ID 番号を表示するだけの小さなアプリケーションを呼び出すように Apache (mod-wsgi を使用) をセットアップしました。
import thread
def application(environ, start_response)
start_response('200 Ok', [('Content-type', 'text/plain')])
output = "current thread id: %s" % thread.get_ident()
return [output]
しばらくすると、同じスレッドが後続のリクエストで再利用されていることに気付きました。
私の理解が正しければ、アプリケーションに「コンテキスト固有の」変数を持たせるには、次のようなスキームでそれらを保存する必要があります。
lock = thread.allocate_lock()
lock.acquire()
thread_id = get_ident()
threadsafe[thread_id]['user'] = request.username
lock.release()
その後、同様の方法で、アプリケーションの別の部分からそれらにアクセスできます。この場合の唯一の保証は、値がその特定のスレッドに属していることです。ただし、同じスレッドを使用するリクエストは、依然としてお互いに足を踏み入れる可能性があります (たとえば、前のリクエストの残りの値にアクセスするリクエスト)。私の結論は、「thread_id」に加えて、各リクエストを真に一意の方法で処理するには、同じスレッドを使用するリクエストを区別できる別のキーが必要になるということです。
uuidなどの一意のキーを使用して、これを行うことができました
lock.acquire()
uuid = uuid.uuid4()
thread_id = get_ident()
threadsafe[(thread_id, uuid)]['user'] = request.username
lock.release()
ただし、これは、後で thread_id を取得できるのと同じ方法で、スレッドセーフな方法で uuid 値も取得する方法があることを意味します。
私は正しい結論を導き出しましたか?もしそうなら、どうすればその追加のキーを取得できますか?
編集
私の問題が誤った二分法であることに気づきました。実際にはこれが不可能な場合でも、スレッドがそれ自体と同時に実行される可能性があるという観点で物事に取り組んでいます。同じスレッドを使用するリクエストは、連続して実行する必要があります。したがって、実際には uuid を使用してスレッドの古い値の使用を避けることができましたが、それはそれをスレッド保存値自体として保存した後でのみでした。
# somewhere early in the request
threadsafe[thread_id]['current_uuid'] = uuid.uuid4()
# later
lock.acquire()
thread_id = get_ident()
uuid = threadsafe[thread_id]['current_uuid']
threadsafe[(thread_id, uuid)]['user'] = request.username
lock.release()