我自己写了一个多进程下载网络大文件的程序:基本思路是多进程分块下载完后,再拼接文件。
这个url的大文件被分割成20个部分,开启了4个进程下载。
vim mpdown.py
import requests
n = 20
url = "https://laotzu.ftp.acc.umu.se/debian-cd/current/amd64/iso-cd/debian-11.7.0-amd64-netinst.iso"
response = requests.get(url, stream=True)
file_size = int(response.headers['content-length'])
a,b = divmod(file_size,n)
def range_down(i):
if i == n-1:
start = i * a
end = file_size - 1
else:
start = i * a
end = (i+1)*a - 1
dst = '/tmp/tmp' + str(i) + '.part'
header = {"Range": "bytes={}-{}".format(start,end)}
req = requests.get(url, headers=header)
with(open(dst, 'ab')) as f:
f.write(req.content)
def merge():
f = open('/tmp/result','ab+')
for i in range(0,n):
fname = '/tmp/tmp' + str(i) + '.part'
ftmp = open(fname,'rb')
f.write(ftmp.read())
ftmp.close()
f.close()
if __name__ == '__main__':
from multiprocessing import Pool
pool = Pool(processes = 4)
for i in range(0,n):
pool.apply_async(range_down,args=(i,))
pool.close()
pool.join()
merge()
测试运行: python3 mpdown.py #速度比单进程快50%以上。
现在我有点不满意这个多进程下载,拼接文件(merge)是在全部下载完成后,再拼接,我想这个拼接动作也修改成多进程并行的,边下载边拼接。
由于下载是多进程的,各进程存在一定的竞争
/tmp/tmp0.part,/tmp/tmp1.part,/tmp/tmp2.part,/tmp/tmp3.part,/tmp/tmp4.part,这些文件不会完全按照顺序产生,考虑使用生产者消费者模型,生产者下载文件,消费者拼接文件,但是如何解决文件顺序在下载过程中不一致的问题?
让拼接文件这个过程也动态起来。
from multiprocessing import Process, Queue
def downloader(queue, i):
# 下载文件
# ...
queue.put(i)
def merger(queue):
next_to_merge = 0
while True:
i = queue.get()
if i == next_to_merge:
# 拼接文件
# ...
next_to_merge += 1
else:
queue.put(i)
if __name__ == '__main__':
queue = Queue()
for i in range(n):
Process(target=downloader, args=(queue, i)).start()
Process(target=merger, args=(queue,)).start()
同时运行4个进程,这4个进程会调用同一个作用域在全局的函数(4个进程的代码片段有相同部分,有不同部分),这4个进程的运行速度是否会因此受到影响? 我是否需要先深拷贝这个全局函数4份,然后每个进程,传递一个同样函数的深拷贝(伪装成4个函数),这样做,整体的程序,运行会更快吧? 这样可以避免万一发生4个进程同时调用一个函数,起冲突? 下面有这样的伪代码表示我的基本意思: global_fun()在四
本地机器上的文档结构: 有上面的文档结构, 推送到github时,仅仅推送这些 推送到gitee时,仅仅推送这些 如何写git push ?
由于全局解释器锁的存在,python3的多线程是伪并行的。 现在看进程。如果一个CPU仅仅有4个核,我在设置pool的时候,设置Pool(5),此时,有5个并行的进程在同时运行,这个说法不对吧,任何时刻,由于CPU的束缚,仅仅只可以有4个进程并行。 我的理解对吧?
这种效果如何使用THREEjs实现?
点击输入框前: 点击输入框后: