簡體   English   中英

Python請求在gevent greenlets之間共享Session對象,線程安全(在greenlets之間)?

[英]Is a Python requests Session object shared between gevent greenlets, thread-safe (between greenlets)?

可以在gevented程序中安全地跨greenlet使用請求庫會話對象嗎?

編輯 - 添加更多解釋:

當greenlet因為已經發出套接字調用將請求發送到服務器而產生時,另一個greenlet是否可以安全地使用同一個套接字(在共享會話對象內)發送自己的請求?

結束編輯

我試圖用這里發布的代碼測試這個 - https://gist.github.com/donatello/0b399d0353cb29dc91b0 - 但我沒有錯誤或意外的結果。 但是,這不會驗證線程安全性。

在測試中,我使用共享會話對象來發出大量請求,並嘗試查看對象是否混淆了請求 - 這有點天真,但我沒有任何例外。

為方便起見,我在這里重新粘貼代碼:

client.py

import gevent
from gevent.monkey import patch_all
patch_all()

import requests
import json

s = requests.Session()

def make_request(s, d):
    r = s.post("http://127.0.0.1:5000", data=json.dumps({'value': d}))
    if r.content.strip() != str(d*2):
        print("Sent %s got %s" % (r.content, str(d*2)))
    if r.status_code != 200:
        print(r.status_code)
        print(r.content)

gevent.joinall([
    gevent.spawn(make_request, s, v)
    for v in range(300)
])

server.py

from gevent.wsgi import WSGIServer
from gevent.monkey import patch_all

patch_all()

from flask import Flask
from flask import request

import time
import json

app = Flask(__name__)

@app.route('/', methods=['POST', 'GET'])
def hello_world():
    d = json.loads(request.data)
    return str(d['value']*2)

if __name__ == '__main__':
    http_server = WSGIServer(('', 5000), app)
    http_server.serve_forever()

精確的庫版本:

requirements.txt

Flask==0.10.1
Jinja2==2.7.2
MarkupSafe==0.23
Werkzeug==0.9.4
argparse==1.2.1
gevent==1.0.1
greenlet==0.4.2
gunicorn==18.0
itsdangerous==0.24
requests==2.3.0
wsgiref==0.1.2

是否有其他測試可以檢查greenlet線程的安全性? 請求文檔在這一點上不太清楚。

requests的作者還創建了一個gevent包: grequests 改用它。

它支持使用session關鍵字傳遞session

import grequests

s = requests.Session()

requests = [grequests.post("http://127.0.0.1:5000", 
                           data=json.dumps({'value': d}), session=s)
            for d in range(300)]

responses = grequests.map(requests)
for r in responses:
    if r.content.strip() != str(d*2):
        print("Sent %s got %s" % (r.content, str(d*2)))
    if r.status_code != 200:
        print(r.status_code)
        print(r.content)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM