现在我正在研究如何尽快从网站获取数据。为了获得更快的速度,我正在考虑使用多线程。这是我用来测试多线程和简单帖子之间差异的代码。
import threading
import time
import urllib
import urllib2
class Post:
def __init__(self, website, data, mode):
self.website = website
self.data = data
#mode is either "Simple"(Simple POST) or "Multiple"(Multi-thread POST)
self.mode = mode
def post(self):
#post data
req = urllib2.Request(self.website)
open_url = urllib2.urlopen(req, self.data)
if self.mode == "Multiple":
time.sleep(0.001)
#read HTMLData
HTMLData = open_url.read()
print "OK"
if __name__ == "__main__":
current_post = Post("http://forum.xda-developers.com/login.php", "vb_login_username=test&vb_login_password&securitytoken=guest&do=login", \
"Simple")
#save the time before post data
origin_time = time.time()
if(current_post.mode == "Multiple"):
#multithreading POST
for i in range(0, 10):
thread = threading.Thread(target = current_post.post)
thread.start()
thread.join()
#calculate the time interval
time_interval = time.time() - origin_time
print time_interval
if(current_post.mode == "Simple"):
#simple POST
for i in range(0, 10):
current_post.post()
#calculate the time interval
time_interval = time.time() - origin_time
print time_interval
正如您所看到的,这是一个非常简单的代码。首先我将模式设置为“简单”,我可以获得时间间隔:50s(也许我的速度有点慢:()。然后我将模式设置为“多个”,然后我得到时间间隔:35。由此可见,多线程确实可以提高速度,但结果却没有我想象的那么好。我想要更快的速度。
通过调试,我发现程序主要阻塞在以下行:open_url = urllib2.urlopen(req, self.data)
,这行代码需要花费大量时间从指定网站发送和接收数据。我想也许我可以通过添加来获得更快的速度time.sleep()
并在内部使用多线程urlopen
函数,但我不能这样做,因为它是 python 自己的函数。
如果不考虑服务器阻塞发布速度的可能限制,我还能做些什么来获得更快的速度?或者我可以修改的任何其他代码?多谢!
你做错的最大的事情,对你的吞吐量影响最大的是你调用的方式thread.start()
and thread.join()
:
for i in range(0, 10):
thread = threading.Thread(target = current_post.post)
thread.start()
thread.join()
每次循环时,您都会创建一个线程,启动它,然后等待它完成在继续下一个线程之前。你根本没有同时做任何事情!
你可能应该做的是:
threads = []
# start all of the threads
for i in range(0, 10):
thread = threading.Thread(target = current_post.post)
thread.start()
threads.append(thread)
# now wait for them all to finish
for thread in threads:
thread.join()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)