python - 用于加密多个文件的多线程或多处理

标签 python multithreading encryption python-multiprocessing

我创建了一个函数 enc()

def enc():
    password = bytes('asd123','utf-8')
    salt = bytes('asd123','utf-8')
    kdf = PBKDF2HMAC(
        algorithm=hashes.SHA256(),
        length=32,
        salt=salt,
        iterations=10000,
        backend=default_backend())
    key = base64.urlsafe_b64encode(kdf.derive(password))
    f = Fernet(key)

    for file in files:
        with open(file,'rb') as original_file:
            original = original_file.read()

        encrypted = f.encrypt(original)

        with open (file,'wb') as encrypted_file:
            encrypted_file.write(encrypted)
它遍历文件中的每个文件并对其进行加密。
files = ['D:/folder/asd.txt',
          'D:/folder/qwe.mp4',
          'D:/folder/qwe.jpg']
我想使用多线程或多处理来使其更快。是否可以?
需要一些代码帮助。
我试过多线程
thread = threading.Thread(target=enc)
thread.start()
thread.join()
但它似乎并没有提高速度或时间。我需要一些帮助来实现多处理。
谢谢。

最佳答案

线程不是 CPU 密集型任务的最佳候选,除非任务正在执行,例如,由释放全局解释器锁的 C 语言库例程执行。无论如何,除非您并行运行多个进程,否则您肯定会通过多线程或多处理获得任何性能提升。
假设您有 N 个任务和 M 个处理器来处理这些任务。如果任务是没有 I/O 的纯 CPU(不完全是您的情况),那么启动多于 M 个进程来处理您的 N 个任务并没有优势,为此,多处理池是理想的情况。当 CPU 和 I/O 混合使用时,池大小大于 M 可能是有利的,如果 I/O 很多而 CPU 很少,则池大小甚至可能大到 N。但在那种情况下,实际使用多线程池和多处理池(大小为 M)的组合会更好,其中多线程池用于所有 I/O 工作,多处理池用于 CPU 计算。以下代码显示了该技术:

from multiprocessing.pool import Pool, ThreadPool
from multiprocessing import cpu_count
from functools import partial

def encrypt(key, b):
    f = Fernet(key)
    return f.encrypt(b)

def enc(key, process_pool, file):
    with open(file,'rb') as original_file:
        original = original_file.read()

    encrypted = process_pool.apply(encrypt, args=(key, original,))

    with open (file,'wb') as encrypted_file:
        encrypted_file.write(encrypted)


def main():
    password = bytes('asd123','utf-8')
    salt = bytes('asd123','utf-8')
    kdf = PBKDF2HMAC(
        algorithm=hashes.SHA256(),
        length=32,
        salt=salt,
        iterations=10000,
        backend=default_backend())
    key = base64.urlsafe_b64encode(kdf.derive(password))

    files = ['D:/folder/asd.txt',
              'D:/folder/qwe.mp4',
              'D:/folder/qwe.jpg']

    # compute number of processes in our pool
    # the lesser of number of files to process and the number of cores we have:
    pool_size = min(cpu_count(), len(files))
    # create process pool:
    process_pool = Pool(pool_size)
    # create thread pool:
    thread_pool = ThreadPool(len(files))
    worker = partial(enc, key, process_pool)
    thread_pool.map(worker, files)

if __name__ == '__main__':
    main()
评论
无论如何,重点是:假设您有 30 个文件和 4 个内核,而不是 3 个文件。 @anarchy 发布的解决方案将启动 30 个进程和计算 f 30 次但实际上只能有效利用 4 个处理器来并行计算 f并进行加密。我的解决方案将使用 30 个线程进行 I/O,但只启动 4 个进程,因此计算 f只有 4 次。您节省了创建 f 的 26 个进程和 26 个计算。那是没用的。
除非您有固态驱动器,否则线程数少于 30 甚至可能更好,因为您的所有线程都在与同一个驱动器竞争,并且 (1) 每个文件可能位于驱动器上完全不同的位置并执行并发 I/O 针对此类文件可能会适得其反,并且 (2) 任何特定驱动器都可以实现一些最大吞吐量。
所以也许我们应该有:

    thread_pool = ThreadPool(max(len(files), MAX_THREADS))
哪里MAX_THREADS设置为适合您的特定驱动器的某个最大值。
更新
现在昂贵的计算key只做一次。

关于python - 用于加密多个文件的多线程或多处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69872049/

相关文章:

java - 如何在线程结束时执行函数?

c++ - 在运行时选择互斥量或虚拟互斥量

php - 使用 Ajax 和 jQuery 通过 PHP 脚本登录用户,是否安全?

python - ggplot2 hell 与 rpy2-2.0.7 + python 2.6 + r 2.11 (windows 7)

python - Redis-py hset() 映射 - 设置多个项目值时出现 TypeError

python - reshape pandas 数据框,将分类列转换为单独的列

python - 打印时不会出现日语字符

android - TextView setText 不刷新文本

curl - 如何在 Linux 上加密密码并传递给 CURL 命令

encryption - 应用程序运行时 GPG 失败