我有一个程序在无限循环中运行大量的urllib请求,这使我的程序真的很慢,所以我尝试将它们作为线程。 Urllib在套接字模块中使用cpython内部深处,因此正在创建的线程只是加起来并且什么也不做,因为python的GIL会阻止两个cpython命令同时在diffident线程中执行。我使用Python 2.5运行Windows XP,因此我无法使用多进程模块。我试着查看子进程模块,看看是否有办法以某种方式在子进程中执行python代码,但没有。如果有人可以通过多进程中的函数创建python子进程,那就太棒了。
另外,我宁愿不下载外部模块,但我愿意。
编辑:以下是我当前程序中一些代码的示例。
url = "http://example.com/upload_image.php?username=Test&password=test"
url = urllib.urlopen(url, data=urllib.urlencode({"Image": raw_image_data})).read()
if url.strip().replace("\n", "") != "":
print url
我做了一个测试,结果发现urllib2的urlopen与Request对象并没有仍然是慢或慢。我创建了自己的自定义时间模块,上面大概需要0.5-2秒,这对我的程序来说非常糟糕。
答案 0 :(得分:1)
Urllib在套接字模块中深入使用cpython,所以线程 正在创建的只是加起来并且什么也不做因为python的GIL 防止两个cpython命令在diffident中执行 线程在同一时间。
错误。虽然这是一种常见的误解。 CPython可以并且确实为IO操作释放GIL(查看socketmodule.c
中的所有Py_BEGIN_ALLOW_THREADS
)。当一个线程等待IO完成其他线程可以做一些工作。如果urllib
调用是您脚本中的瓶颈,那么线程可能是可接受的解决方案之一。
我使用Python 2.5运行Windows XP,因此无法使用多进程模块。
您可以安装Python 2.6或更高版本,或者必须使用Python 2.5;您可以单独安装multiprocessing。
我创建了自己的自定义时间模块,上面大概需要0.5-2秒,这对我的程序来说非常糟糕。
urllib2.urlopen('http://example.com...).read()
的性能主要取决于外部因素,如DNS,网络延迟/带宽,example.com服务器本身的性能。
以下是使用threading
和urllib2
:
import urllib2
from Queue import Queue
from threading import Thread
def check(queue):
"""Check /n url."""
opener = urllib2.build_opener() # if you use install_opener in other threads
for n in iter(queue.get, None):
try:
data = opener.open('http://localhost:8888/%d' % (n,)).read()
except IOError, e:
print("error /%d reason %s" % (n, e))
else:
"check data here"
def main():
nurls, nthreads = 10000, 10
# spawn threads
queue = Queue()
threads = [Thread(target=check, args=(queue,)) for _ in xrange(nthreads)]
for t in threads:
t.daemon = True # die if program exits
t.start()
# provide some work
for n in xrange(nurls): queue.put_nowait(n)
# signal the end
for _ in threads: queue.put(None)
# wait for completion
for t in threads: t.join()
if __name__=="__main__":
main()
要将其转换为多处理脚本,只需使用不同的导入,您的程序将使用多个进程:
from multiprocessing import Queue
from multiprocessing import Process as Thread
# the rest of the script is the same
答案 1 :(得分:0)
如果你想要多线程,Jython可以是一个选项,因为它没有GIL。
我赞同@ Jan-Philip和@Piotr。你在用urllib做什么?