【发布时间】:2014-09-28 14:42:35
【问题描述】:
我通过Process 类使用多处理模块来执行一些不受 cpu 限制的任务,例如I/O 或 Web 请求。如果任务花费的时间太长,CPU 会达到 100% 的使用率(所有线程都在等待数据返回)。我怀疑异步执行解决方案,但我从未做过这样的事情。我正在使用的代码类似于以下内容,其中我有一个巨大的列表,每个进程都在一个块上工作。
您能在这个方向上提出建议吗?
提前致谢!!
import multiprocessing
def getData(urlsChunk, myQueue):
for url in urlsChunk:
fp = urllib.urlopen(url)
try:
data = fp.read()
myQueue.put(data)
finally:
fp.close()
return myQueue
manager = multiprocessing.Manager()
HUGEQ = manager.Queue()
urls = ['a huge list of url items']
chunksize = int(math.ceil(len(urls) / float(nprocs)))
for i in range(nprocs):
p = Process(
target = getData, # This is my worker
args=(urls[chunksize * i:chunksize * (i + 1)],
MYQUEUE
)
)
processes.append(p)
p.start()
for p in processes:
p.join()
while True:
try:
MYQUEUEelem = MYQUEUE.get(block=False)
except Empty:
break
else:
'do something with the MYQUEUEelem'
【问题讨论】:
-
我不明白底部的while循环。你不应该打一个阻塞电话吗?当子进程第一次落后时,父进程会得到一个 Empty 并跳出处理循环。
-
在获取 url 时分块不是一个好主意。分块通过一次发送多个请求来减少父/子开销。不利的一面是孩子现在必须处理所有这些。如果某些 url 很慢,则该客户端上的剩余 url 将不得不等待,即使另一个子进程已完成并准备处理更多。
-
您能多解释一下
blocking call和子进程是什么意思吗? -
您正在创建一组同步获取 url 的子进程。 getData 需要 1 个 url,发出请求,等待请求完成并返回结果。假设您有 100 个网址和 10 个孩子。您可以给每个孩子 10 个网址(块)。但是有些 url 比其他 url 需要更长的时间(可能更长),所以有些孩子比其他孩子更早完成。如果您一次只提交 1 个 url(没有块),那么早完成的孩子会获得额外的 url,您可以更快地完成。
标签: python windows python-2.7 asynchronous multiprocessing