Нужно ли открывать SFTPClient для одного потока в Paramiko с многопоточностью? - PullRequest
0 голосов
/ 19 мая 2018

Я хочу скачивать файлы с удаленного сервера, используя Paramiko с многопоточностью.

Мне пришло в голову два решения, но я не уверен, какое из них правильное (или лучше).

Решение 1: Если предположить, что SFTPClient.get является поточно-ориентированным (но я не могу найти ни одного упомянутого документа), простой будет выглядеть так:

from paramiko import SSHClient, AutoAddPolicy, SFTPClient
from concurrent.futures import ThreadPoolExecutor
from typing import List

client = SSHClient()
ciient.set_missing_host_key_policy(AutoAddPolicy())
client.connect( ... )
sftp = client.open_sftp()

files_to_download: List[str] = ...

with ThreadPoolExecutor(10) as pool:
    pool.map(lambda fn: sftp.get(fn, fn), files_to_download)

Решение 2: В есть два вопроса. Решение 1

  1. Действительно ли API Paramiko действительно поточно-ориентирован?
  2. Эффективно ли загружать несколькофайлы через одно соединение?

Итак, вот мое второе решение:

from paramiko import SSHClient, AutoAddPolicy, SFTPClient
from concurrent.futures import ThreadPoolExecutor
from threading import Lock, local
from typing import List

client = SSHClient()
ciient.set_missing_host_key_policy(AutoAddPolicy())
client.connect( ... )
thread_local = local()
thread_lock  = Lock()

files_to_download: List[str] = ...

def download(fn: str) -> None:
    """
    thread-safe and each thread has its own SFTPClient
    """
    if not hasattr(thread_local, 'sftp'):
        with thread_lock:
            thread_local.sftp = client.open_sftp()
    thread_local.sftp.get(fn, fn)

with ThreadPoolExecutor(10) as pool:
    pool.map(download, files_to_download)

Какое решение лучше?

1 Ответ

0 голосов
/ 19 мая 2018

Paramiko не является потокобезопасным.

Использование нескольких потоков в одном соединении в любом случае не даст вам никакого выигрыша в производительности.

Вы должны открыть отдельное соединение для потока.

...