Pythonの人気のある Requests ライブラリは、そのホームページではスレッドセーフであると言われていますが、それ以上の詳細は提供されていません。 requests.session()
を呼び出すと、このオブジェクトを安全に複数のスレッドに渡すことができますか?
session = requests.session()
for i in xrange(thread_count):
threading.Thread(
target=target,
args=(session,),
kwargs={}
)
複数のスレッドで同じ接続プールを使用してリクエストを作成しますか?
もしそうなら、これは推奨されるアプローチですか、それとも各スレッドに独自の接続プールを与える必要がありますか? (個々の接続プールすべての合計サイズを合計すると、上記のような1つの大きな接続プールのサイズになると仮定します。)各アプローチの長所と短所は何ですか。
requests.session
のソースを確認した後、使用しているCookieJarの実装によっては、セッションオブジェクトがスレッドセーフである可能性があると言います。
Session.prepare_request
はself.cookies
から読み取り、Session.send
はextract_cookies_to_jar(self.cookies, ...)
を呼び出し、jar.extract_cookies(...)
を呼び出します(この場合、jar
はself.cookies
です)。
Python 2.7のcookielib
のソースは、jarの更新中にロック(threading.RLock
)を取得するため、スレッドセーフであるように見えます。一方、 cookielib
のドキュメント はスレッドセーフについて何も述べていないため、この機能に依存すべきではないでしょうか。
更新
スレッドがheaders
、proxies
、stream
などのセッションオブジェクトの属性を変更している場合、またはmount
メソッドを呼び出すか、セッションを使用している場合with
ステートメントなどでは、スレッドセーフではありません。
https://github.com/kennethreitz/requests/issues/1871 は、セッションがスレッドセーフではなく、少なくとも1人のメンテナがスレッドごとに1つのセッションを推奨することを意味します。
ドキュメントを明確にするために https://github.com/kennethreitz/requests/issues/2766 を開きました。