Загрузка нескольких файлов параллельно с s3 с помощью boto - PullRequest
1 голос
/ 01 мая 2019

http://ls.pwd.io/2013/06/parallel-s3-uploads-using-boto-and-threads-in-python/

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

1 Ответ

1 голос
/ 01 мая 2019

просто немного поиграю, и я вижу, multiprocessing требуется время, чтобы разрушить Пул, но в остальном не так много в нем

тестовый код:

from time import time, sleep
from multiprocessing.pool import Pool, ThreadPool
from threading import Thread


N_WORKER_JOBS = 10


def worker(x):
    # print("working on", x)
    sleep(0.1)


def mp_proc(fn, n):
    start = time()
    with Pool(N_WORKER_JOBS) as pool:
        t1 = time() - start
        pool.map(fn, range(n))
        start = time()
    t2 = time() - start
    print(f'Pool creation took {t1*1000:.2f}ms, teardown {t2*1000:.2f}ms')


def mp_threads(fn, n):
    start = time()
    with ThreadPool(N_WORKER_JOBS) as pool:
        t1 = time() - start
        pool.map(fn, range(n))
        start = time()
    t2 = time() - start
    print(f'ThreadPool creation took {t1*1000:.2f}ms, teardown {t2*1000:.2f}ms')


def threads(fn, n):
    threads = []
    for i in range(n):
        t = Thread(target=fn, args=(i,))
        threads.append(t)
        t.start()
    for t in threads:
        t.join()


for test in [mp_proc, mp_threads, threads]:
    times = []
    for _ in range(7):
        start = time()
        test(worker, 10)
        times.append(time() - start)

    times = ', '.join(f'{t*1000:.2f}' for t in times)
    print(f'{test.__name__} took {times}ms')

Я получаю следующее время (Python 3.7.3, Linux 5.0.8):

  • mp_proc ~ 220 мс
  • mp_threads ~ 200 мс
  • threads ~ 100 мс

однако время разрыва составляет все ~ 100 мс, что приводит все в основном в соответствие.

Я возился с ведением журнала и в источнике, и, кажется, это из-за того, что _handle_workers проверяет только каждые 100 мс (он проверяет состояние, затем спит 0,1 секунды).

с этим знанием я могу сменить код на 0,095 секунды, тогда все будет в пределах 10% друг от друга. Кроме того, учитывая, что это только один раз при сносе пула, легко организовать, чтобы это не происходило во внутреннем цикле

...