Python中如何使用gevent进行异步请求并获取返回值
import gevent.monkey
gevent.monkey.patch_socket()
import gevent
import urllib2
import simplejson as json
def fetch(pid):
response = urllib2.urlopen(‘http://json-time.appspot.com/time.json’)
result = response.read()
json_result = json.loads(result)
datetime = json_result[‘datetime’]
print 'Process ', pid, datetime
return json_result[‘datetime’]
def asynchronous():
threads = []
for i in range(1,10):
threads.append(gevent.spawn(fetch, i))
gevent.joinall(threads)
我想得到 fetch 里面那个 return 的返回值,在 gevent.spawn 的情况下怎么才能得到 spawn 的函数里 return 的值啊
Python中如何使用gevent进行异步请求并获取返回值
import gevent
from gevent import monkey
import requests
# 打补丁让标准库支持异步
monkey.patch_all()
def fetch_url(url):
"""异步获取单个URL的内容"""
try:
response = requests.get(url, timeout=5)
return {
'url': url,
'status': response.status_code,
'content': response.text[:100] # 只取前100字符
}
except Exception as e:
return {
'url': url,
'error': str(e)
}
def async_fetch_urls(url_list):
"""并发获取多个URL"""
# 创建协程任务
jobs = [gevent.spawn(fetch_url, url) for url in url_list]
# 等待所有协程完成
gevent.joinall(jobs)
# 获取所有结果
results = [job.value for job in jobs]
return results
if __name__ == "__main__":
# 测试URL列表
urls = [
'https://httpbin.org/get',
'https://api.github.com',
'https://www.python.org'
]
# 执行异步请求
results = async_fetch_urls(urls)
# 打印结果
for result in results:
print(f"URL: {result.get('url')}")
if 'status' in result:
print(f" Status: {result['status']}")
print(f" Preview: {result['content']}")
else:
print(f" Error: {result['error']}")
print("-" * 50)
核心要点:
- monkey.patch_all() - 必须调用这个来让标准库(如requests)支持异步
- gevent.spawn() - 创建协程任务,不立即执行
- gevent.joinall() - 等待所有协程执行完成
- job.value - 获取协程的返回值
高级用法:使用gevent的Pool控制并发数:
from gevent.pool import Pool
def fetch_with_pool(urls, concurrency=3):
"""使用连接池控制并发数"""
pool = Pool(concurrency)
results = pool.map(fetch_url, urls)
return results
# 使用示例
urls = ['https://httpbin.org/get'] * 10 # 10个相同请求
results = fetch_with_pool(urls, concurrency=5) # 最多5个并发
关键提醒:
- gevent是基于协程的异步,不是多线程/多进程
- 所有协程在同一个线程中运行
- I/O阻塞时自动切换协程
- 适合I/O密集型任务,不适合CPU密集型
一句话建议:用gevent.spawn创建协程,gevent.joinall等待结果,job.value获取返回值。
或者说,我并不太理解在并发执行函数时怎么能得到每个函数的返回值? 不用 gevent 有别的方法吗
这么简单问题还用问?
import queue
q = queue.Queue(maxsize=0)
把 return 改成
q.put( json_result[‘datetime’])
用 q.get()一个一个取,或者 list(q.queue) 一起取
我就是这么取的,只是想知道 return 能不能 直接得到
你 return 给谁呀?
那样就成了顺序调用无法并发了。
嗯嗯,我理解一点了,谢谢
from gevent import monkey
monkey.patch_socket()
monkey.patch_ssl()
import gevent
import requests
import simplejson as json
from tornado import gen
.coroutine
def fetch(pid):
response = requests.get(‘https://www.baidu.com’)
result = response.text
# json_result = json.loads(result)
# datetime = json_result[‘datetime’]
print('Process ', result)
raise gen.Return(result)
# return result
def asynchronous():
threads = []
for i in range(1,10):
threads.append(gevent.spawn(fetch, i))
gevent.joinall(threads)
可以这样

