python支持断点续传的多线程下载示例
#! /usr/bin/env python
#coding=utf-8
from __future__ import unicode_literals
from multiprocessing.dummy import Pool as ThreadPool
import threading
import os
import sys
import cPickle
from collections import namedtuple
import urllib2
from urlparse import urlsplit
import time
# global lock
lock = threading.Lock()
# default parameters
defaults = dict(thread_count=10,
buffer_size=10*1024,
block_size=1000*1024)
def progress(percent, width=50):
print "%s %d%%\r" % (('%%-%ds' % width) % (width * percent / 100 * '='), percent),
if percent >= 100:
print
sys.stdout.flush()
def write_data(filepath, data):
with open(filepath, 'wb') as output:
cPickle.dump(data, output)
def read_data(filepath):
with open(filepath, 'rb') as output:
return cPickle.load(output)
FileInfo = namedtuple('FileInfo', 'url name size lastmodified')
def get_file_info(url):
class HeadRequest(urllib2.Request):
def get_method(self):
return "HEAD"
res = urllib2.urlopen(HeadRequest(url))
res.read()
headers = dict(res.headers)
size = int(headers.get('content-length', 0))
lastmodified = headers.get('last-modified', '')
name = None
if headers.has_key('content-disposition'):
name = headers['content-disposition'].split('filename=')[1]
if name[0] == '"' or name[0] == "'":
name = name[1:-1]
else:
name = os.path.basename(urlsplit(url)[2])
return FileInfo(url, name, size, lastmodified)
def download(url, output,
thread_count = defaults['thread_count'],
buffer_size = defaults['buffer_size'],
block_size = defaults['block_size']):
# get latest file info
file_info = get_file_info(url)
# init path
if output is None:
output = file_info.name
workpath = '%s.ing' % output
infopath = '%s.inf' % output
# split file to blocks. every block is a array [start, offset, end],
# then each greenlet download filepart according to a block, and
# update the block' offset.
blocks = []
if os.path.exists(infopath):
# load blocks
_x, blocks = read_data(infopath)
if (_x.url != url or
_x.name != file_info.name or
_x.lastmodified != file_info.lastmodified):
blocks = []
if len(blocks) == 0:
# set blocks
if block_size > file_info.size:
blocks = [[0, 0, file_info.size]]
else:
block_count, remain = divmod(file_info.size, block_size)
blocks = [[i*block_size, i*block_size, (i+1)*block_size-1] for i in range(block_count)]
blocks[-1][-1] += remain
# create new blank workpath
with open(workpath, 'wb') as fobj:
fobj.write('')
print 'Downloading %s' % url
# start monitor
threading.Thread(target=_monitor, args=(infopath, file_info, blocks)).start()
# start downloading
with open(workpath, 'rb+') as fobj:
args = [(url, blocks[i], fobj, buffer_size) for i in range(len(blocks)) if blocks[i][1]
if thread_count > len(args):
thread_count = len(args)
pool = ThreadPool(thread_count)
pool.map(_worker, args)
pool.close()
pool.join()
# rename workpath to output
if os.path.exists(output):
os.remove(output)
os.rename(workpath, output)
# delete infopath
if os.path.exists(infopath):
os.remove(infopath)
assert all([block[1]>=block[2] for block in blocks]) is True
def _worker((url, block, fobj, buffer_size)):
req = urllib2.Request(url)
req.headers['Range'] = 'bytes=%s-%s' % (block[1], block[2])
res = urllib2.urlopen(req)
while 1:
chunk = res.read(buffer_size)
if not chunk:
break
with lock:
fobj.seek(block[1])
fobj.write(chunk)
block[1] += len(chunk)
def _monitor(infopath, file_info, blocks):
while 1:
with lock:
percent = sum([block[1] - block[0] for block in blocks]) * 100 / file_info.size
progress(percent)
if percent >= 100:
break
write_data(infopath, (file_info, blocks))
time.sleep(2)
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='Download file by multi-threads.')
parser.add_argument('url', type=str, help='url of the download file')
parser.add_argument('-o', type=str, default=None, dest="output", help='output file')
parser.add_argument('-t', type=int, default=defaults['thread_count'], dest="thread_count", help='thread counts to downloading')
parser.add_argument('-b', type=int, default=defaults['buffer_size'], dest="buffer_size", help='buffer size')
parser.add_argument('-s', type=int, default=defaults['block_size'], dest="block_size", help='block size')
argv = sys.argv[1:]
if len(argv) == 0:
argv = ['https://eyes.nasa.gov/eyesproduct/EYES/os/win']
args = parser.parse_args(argv)
start_time = time.time()
download(args.url, args.output, args.thread_count, args.buffer_size, args.block_size)
print 'times: %ds' % int(time.time()-start_time)

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas











Pengendalian pengecualian fungsi dalam C++ amat penting untuk persekitaran berbilang benang untuk memastikan keselamatan benang dan integriti data. Pernyataan cuba-tangkap membolehkan anda menangkap dan mengendalikan jenis pengecualian tertentu apabila ia berlaku untuk mengelakkan ranap program atau rasuah data.

PHP multithreading merujuk kepada menjalankan berbilang tugas secara serentak dalam satu proses, yang dicapai dengan mencipta benang berjalan secara bebas. Anda boleh menggunakan sambungan Pthreads dalam PHP untuk mensimulasikan tingkah laku berbilang benang Selepas pemasangan, anda boleh menggunakan kelas Thread untuk mencipta dan memulakan utas. Contohnya, apabila memproses sejumlah besar data, data boleh dibahagikan kepada berbilang blok dan bilangan benang yang sepadan boleh dibuat untuk memprosesnya secara serentak untuk meningkatkan kecekapan.

Teknik concurrency dan multithreading menggunakan fungsi Java boleh meningkatkan prestasi aplikasi, termasuk langkah berikut: Memahami konsep concurrency dan multithreading. Manfaatkan pustaka konkurensi dan berbilang benang Java seperti ExecutorService dan Callable. Amalkan kes seperti pendaraban matriks berbilang benang untuk memendekkan masa pelaksanaan. Nikmati kelebihan peningkatan kelajuan tindak balas aplikasi dan kecekapan pemprosesan yang dioptimumkan yang dibawa oleh concurrency dan multi-threading.

Dalam persekitaran berbilang benang, gelagat fungsi PHP bergantung pada jenisnya: Fungsi biasa: thread-safe, boleh dilaksanakan secara serentak. Fungsi yang mengubah suai pembolehubah global: tidak selamat, perlu menggunakan mekanisme penyegerakan. Fungsi operasi fail: tidak selamat, perlu menggunakan mekanisme penyegerakan untuk menyelaraskan akses. Fungsi operasi pangkalan data: Mekanisme sistem pangkalan data yang tidak selamat perlu digunakan untuk mengelakkan konflik.

Terdapat dua pendekatan biasa apabila menggunakan JUnit dalam persekitaran berbilang benang: ujian berbenang tunggal dan ujian berbilang benang. Ujian berutas tunggal dijalankan pada utas utama untuk mengelakkan isu konkurensi, manakala ujian berbilang utas dijalankan pada utas pekerja dan memerlukan pendekatan ujian disegerakkan untuk memastikan sumber yang dikongsi tidak terganggu. Kes penggunaan biasa termasuk menguji kaedah selamat berbilang benang, seperti menggunakan ConcurrentHashMap untuk menyimpan pasangan nilai kunci, dan utas serentak untuk beroperasi pada pasangan nilai kunci dan mengesahkan ketepatannya, mencerminkan aplikasi JUnit dalam persekitaran berbilang benang. .

Mutex digunakan dalam C++ untuk mengendalikan sumber perkongsian berbilang benang: buat mutex melalui std::mutex. Gunakan mtx.lock() untuk mendapatkan mutex dan menyediakan akses eksklusif kepada sumber yang dikongsi. Gunakan mtx.unlock() untuk melepaskan mutex.

Dalam persekitaran berbilang benang, pengurusan memori C++ menghadapi cabaran berikut: perlumbaan data, kebuntuan dan kebocoran memori. Tindakan balas termasuk: 1. Menggunakan mekanisme penyegerakan, seperti mutex dan pembolehubah atom 2. Menggunakan struktur data tanpa kunci 3. Menggunakan penunjuk pintar 4. (Pilihan) Melaksanakan pengumpulan sampah;

Pengujian program berbilang benang menghadapi cabaran seperti ketidakbolehulangan, ralat konkurensi, kebuntuan dan kekurangan keterlihatan. Strategi termasuk: Ujian unit: Tulis ujian unit untuk setiap utas untuk mengesahkan kelakuan utas. Simulasi berbilang benang: Gunakan rangka kerja simulasi untuk menguji program anda dengan kawalan ke atas penjadualan benang. Pengesanan perlumbaan data: Gunakan alat untuk mencari perlumbaan data yang berpotensi, seperti valgrind. Nyahpepijat: Gunakan penyahpepijat (seperti gdb) untuk memeriksa status program masa jalan dan mencari sumber perlumbaan data.
