При загрузке большого количества файлов с многопоточностью в Python некоторые файлы "отстают" - PullRequest
0 голосов
/ 12 июля 2020

Я загружаю большое количество файлов с того же сервера в Python, используя многопоточность. В качестве примера, чтобы быть более конкретным, я попытался загрузить 12 файлов одновременно, используя 12 потоков. Заметил, что 10 файлов загружаются относительно быстро, а 2 отстают. Даже когда загрузка 10 файлов завершена, скорость загрузки 2 других файлов очень низкая. Если я затем снова попробую загрузить эти 2 файла, скорость будет намного лучше. Так что именно происходит и как я могу это исправить?

PS: Я попытался уменьшить количество потоков до 8, поэтому 8 файлов загружались одновременно, и у меня был 1 файл, который снова отставал от остальных.

PPS: Затем я попытался уменьшить количество потоков до 6, и снова та же проблема. Один файл будет лагать. У меня нет этой проблемы, если я загружаю напрямую из Firefox и получаю значительное ускорение, но я пытаюсь автоматизировать процесс, поэтому загрузка из Firefox не является вариантом.

Для справки вот код:

import queue
import threading
import time


start = time.perf_counter()

    
class MyThread(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name
    def run(self):
        print('Starting thread %s.' % self.name)
        process_queue()
        print('Exiting thread %s.' % self.name)
        
def process_queue():
    while True:
        try:
            url = my_queue.get(block=False)
            filename = url.split('/')[-1]
            with closing(request.urlopen(url)) as r:
                with open(filename, 'wb') as f:
                    shutil.copyfileobj(r, f)
        except queue.Empty:
            return
        
# setting up variables
urls = [
        'ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR824/000/SRR8240860/SRR8240860_1.fastq.gz',
        'ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR824/000/SRR8240860/SRR8240860_2.fastq.gz',
        'ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR824/001/SRR8240861/SRR8240861_1.fastq.gz',
        'ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR824/001/SRR8240861/SRR8240861_2.fastq.gz',
        'ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR824/002/SRR8240862/SRR8240862_1.fastq.gz',
        'ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR824/002/SRR8240862/SRR8240862_2.fastq.gz',
        'ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR824/003/SRR8240863/SRR8240863_1.fastq.gz',
        'ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR824/003/SRR8240863/SRR8240863_2.fastq.gz',
        'ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR824/004/SRR8240864/SRR8240864_1.fastq.gz',
        'ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR824/004/SRR8240864/SRR8240864_2.fastq.gz',
        'ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR824/005/SRR8240865/SRR8240865_1.fastq.gz',
        'ftp://ftp.sra.ebi.ac.uk/vol1/fastq/SRR824/005/SRR8240865/SRR8240865_2.fastq.gz',
        ]

# filling the queue
my_queue = queue.Queue()

for url in urls:
    my_queue.put(url)

# initializing and starting num_threads threads
num_threads = 8
threads = []

for i in range(num_threads):
    thread = MyThread(i)
    threads.append(thread)

for thread in threads:
    thread.start()

for thread in threads:
    thread.join()
    
finish = time.perf_counter()

print(f'Finished in {round(finish-start, 2)} second(s)')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...