Python 线程与非线程

1 投票
1 回答
889 浏览
提问于 2025-04-18 05:27

我现在正在尝试一个用Python写的压缩文件密码破解工具,这个工具是多线程的。我原以为新开一个线程就像是新开一个连接,可以更快地完成工作。但是,当我去掉线程后,测量了时间,结果让我大吃一惊,性能竟然下降了六倍(慢了六倍)。我会把代码放在这里,以防这就是问题所在。

import zipfile
from threading import Thread

def extractFile(zFile, password):
    try:
        zFile.extractall(pwd=password)
        print '[+] Password:', password
    except:
        pass

def main():
    zFile = zipfile.ZipFile('encrypted.zip')
    passFile = open('dictionary.txt', 'r')
    for line in passFile.readlines():
        password = line.strip('\n')
        t = Thread(target=extractFile, args=(zFile,password))   
        t.start()

if __name__ == '__main__':
    main()

一旦我去掉了线程,完成的速度快了六倍。时间结果如下:

使用线程

real    18m46.974s 
user    18m25.936s   
sys     9m6.872s

不使用线程

real    3m32.674s
user    3m6.400s
sys     0m25.664s

这是为什么呢?我原本以为使用多线程的方法会提高性能。

相关问题:

1 个回答

3

这种方法有两个问题:

1) 你创建了 N 个线程,其中 N 是 dictionary.txt 文件中的行数。根据我猜测的行数,这意味着你在一个紧凑的循环中创建了成千上万的线程。一次性运行这么多线程会消耗大量资源,因为每个线程都占用一些内存,而你的 CPU 实际上一次只能运行几个线程(在 Python 中,实际上只能同时运行一个线程,关于这一点在第 2 点会详细说明)。而且,创建线程本身也需要时间,创建这么多线程会让你的程序变得更慢。

2) 由于 全局解释器锁(GIL) 的存在,在 Python 中,实际上一次只能执行一个线程。这就失去了多核 CPU 的优势,通常多核 CPU 应该能同时处理多个线程。你应该使用 multiprocessing 模块,特别是 Pool 类,来实现并行处理。这样可以充分利用多个核心,并且使用 Pool 可以避免创建成千上万的进程,从而让你的系统崩溃。

撰写回答