Dav*_*itz 5 python asynchronous gevent http-request
我们有一系列工作,工人一次处理这些工作.每个作业都要求我们格式化一些数据并发出HTTP POST请求,并将数据作为请求有效负载.
我们如何让每个工作人员以单线程,非阻塞方式异步发出这些HTTP POST请求?我们不关心请求的响应 - 我们想要的只是请求尽快执行,然后让工作人员立即进入下一个工作.
我们已经探索了使用gevent和grequests库(请参阅为什么gevent.spawn在调用Greenlet.join之前不执行参数化函数?).我们的工作代码看起来像这样:
def execute_task(worker, job):
print "About to spawn request"
greenlet = gevent.spawn(requests.post, url, params=params)
print "Request spawned, about to call sleep"
gevent.sleep()
print "Greenlet status: ", greenlet.ready()
Run Code Online (Sandbox Code Playgroud)
执行第一个print语句,但第二个和第三个打印语句永远不会打印,并且永远不会命中url.
我们如何才能执行这些异步请求?
1)创建一个Queue.Queue对象
2)创建任意数量的“工作”线程,循环并从 Queue.Queue 中读取
3)将作业送入Queue.Queue
工作线程将按照它们放置在队列中的顺序读取 Queue.Queue
从文件中读取行并将其放入 Queue.Queue 的示例
import sys
import urllib2
import urllib
from Queue import Queue
import threading
import re
THEEND = "TERMINATION-NOW-THE-END"
#read from file into Queue.Queue asynchronously
class QueueFile(threading.Thread):
def run(self):
if not(isinstance(self.myq, Queue)):
print "Queue not set to a Queue"
sys.exit(1)
h = open(self.f, 'r')
for l in h:
self.myq.put(l.strip()) # this will block if the queue is full
self.myq.put(THEEND)
def set_queue(self, q):
self.myq = q
def set_file(self, f):
self.f = f
Run Code Online (Sandbox Code Playgroud)
工作线程可能是什么样子的想法(仅示例)
class myWorker(threading.Thread):
def run(self):
while(running):
try:
data = self.q.get() # read from fifo
req = urllib2.Request("http://192.168.1.10/url/path")
req.add_data(urllib.urlencode(data))
h1 = urllib2.urlopen(req, timeout=10)
res = h1.read()
assert(len(res) > 80)
except urllib2.HTTPError, e:
print e
except urllib2.URLError, e:
print "done %d reqs " % n
print e
sys.exit()
Run Code Online (Sandbox Code Playgroud)
要使基于 threading.Thread 的对象运行,请创建该对象,然后在实例上调用“start”
| 归档时间: |
|
| 查看次数: |
2880 次 |
| 最近记录: |