При загрузке файлов в несколько потоков в python потоки заканчиваются sh до того, как все файлы станут доступны - PullRequest
0 голосов
/ 04 февраля 2020

При загрузке изображений в несколько потоков некоторые изображения становятся недоступными после завершения всех потоков. Это упрощенный код для загрузки изображения и того, как потоки запускаются и объединяются. Я ожидаю, что все дескрипторы файлов будут освобождены, и файлы будут доступны после того, как очередь потоков пуста.

def download_image(id, link, path):
    response = requests.get(link)
    if response.status_code == 200:
        filename = os.path.join(path, f"{id}.jpg")

    with open( filename, 'wb' ) as file:
        file.write(response.content)



queue = [threading.Thread(target=download_image, args=(id, link, image_dir)) for id, link in photos_to_download]

while queue:
    threads = queue[:thread_amount] # pick 'thread_amount' threads from the queue 
    threads = [t.start() for t in threads] # start the threads
    threads = [t.join() for t in threads if t != None] # wait for the threads to finish execution
    queue = queue[thread_amount:] # remove finished tasks from queue

Однако после завершения потоков не все изображения доступны и с кодом ниже I явно подождите, пока в каталог изображений не добавятся новые файлы.

n_images = len(os.listdir(image_dir))
time.sleep(5)
while len(os.listdir(image_dir)) > n_images: 
    n_images = len(os.listdir(image_dir))
    time.sleep(5)

Это проблема с многопоточностью, библиотекой os или ОС (Windows) не может зарегистрировать новый файлы сразу?

1 Ответ

0 голосов
/ 04 февраля 2020

Проблема состояла в том, что thread.start () возвращает NoneType, и в этих строках я пытался вызвать join из списка None вместо реальных потоков:

threads = [t.start() for t in threads]
threads = [t.join() for t in threads if t != None]
...