在许多情况下,python的线程无法很好地提高执行速度…有时,它会使情况变得更糟。有关更多信息,请参阅全球解释器锁/ Pycon2010
GIL幻灯片上David
Beazley的PyCon2010演示。该演示非常有用,我强烈推荐给任何考虑线程的人…
即使David
Beazley的演讲解释了网络流量可以改善Python线程模块的调度,您仍应使用multiprocessing模块。我将此作为选项包含在您的代码中(请参见答案底部)。
在我的一台旧机器上运行此命令(Python 2.6.6):
current_post.mode == "Process" (multiprocessing) --> 0.2609 secondscurrent_post.mode == "Multiple" (threading) --> 0.3947 secondscurrent_post.mode == "Simple" (serial execution) --> 1.650 seconds
我同意TokenMacGuy的评论,上面的数字包括将
.join()移到另一个循环。如您所见,python的多处理比线程处理快得多。
from multiprocessing import Processimport threadingimport timeimport urllibimport urllib2class Post: def __init__(self, website, data, mode): self.website = website self.data = data #mode is either: # "Simple" (Simple POST) # "Multiple" (Multi-thread POST) # "Process" (Multiprocessing) self.mode = mode self.run_job() 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" def run_job(self): """This was refactored from the OP's pre""" origin_time = time.time() if(self.mode == "Multiple"): #multithreading POST threads = list() for i in range(0, 10): thread = threading.Thread(target = self.post) thread.start() threads.append(thread) for thread in threads: thread.join() #calculate the time interval time_interval = time.time() - origin_time print "mode - {0}: {1}".format(method, time_interval) if(self.mode == "Process"): #multiprocessing POST processes = list() for i in range(0, 10): process = Process(target=self.post) process.start() processes.append(process) for process in processes: process.join() #calculate the time interval time_interval = time.time() - origin_time print "mode - {0}: {1}".format(method, time_interval) if(self.mode == "Simple"): #simple POST for i in range(0, 10): self.post() #calculate the time interval time_interval = time.time() - origin_time print "mode - {0}: {1}".format(method, time_interval) return time_intervalif __name__ == "__main__": for method in ["Process", "Multiple", "Simple"]: Post("http://forum.xda-developers.com/login.php", "vb_login_username=test&vb_login_password&securitytoken=guest&do=login", method )


