Python多处理循环,奇怪的行为

时间:2018-09-23 07:28:15

标签: python python-multiprocessing

我是python的新手,所以下面是一个(写得不好)的脚本,旨在使用“强力”和“字典”之间的一种混合来查找zip的密码。

ex:“ thisisastringdictionnary” =>字典;密码=>“字符串” 该脚本将在一定限制内测试任何可能的子链(例如500个角色)。

下面的脚本可以正常工作,但是非常慢。 这就是为什么我要使用池/多重处理的原因。

脚本,无需多处理(有效):

import zipfile
import thread
import sys
zipfilename = 'toopen.zip'
dictionary = 'dictionnary.txt'
zip_file = zipfile.ZipFile(zipfilename)
def openZip(sub, start, stringLen):
    try:
        zip_file.extractall(pwd=sub)
        sub = 'Password found: %s' % sub
        print sub
        sys.exit(0)
    except SystemExit:
        sys.exit(0)
    except:
        print str((start/float(stringLen))*100)+"%"
        pass
def main():
    password = None
    zip_file = zipfile.ZipFile(zipfilename)
    with open(dictionary, 'r') as f:
        for line in f.readlines():
            password = line.strip('\n')
            for start in range(len(password)):
                for index in range(500):
                    sub = password[start:index+1]
                    openZip(sub, start, len(password));

if __name__ == '__main__':
    main()

在尝试进行多处理后,我遇到了几个问题:

  • 找到密码后脚本不会停止/退出
  • try catch中的打印显示得很奇怪(就像每个进程都在无顺序打印一样)=>因此进度指示器不再有效了
  • 我什至不确定我是否正确地做到了这一点:/

尝试一下

import zipfile
import thread
import sys
from multiprocessing import Pool

zipfilename = 'toopen.zip'
dictionary = 'dictionnary.txt'
zip_file = zipfile.ZipFile(zipfilename)
def openZip(sub):
    try:
        zip_file.extractall(pwd=sub[0])
        sub = 'Password found: %s' % sub[0]
        print sub[0]
        sys.exit(0)
    except SystemExit:
        sys.exit(0)
    except:
        print str((sub[1]/float(sub[2]))*100)+"%"
        pass
def main():
    p = Pool(4)

    password = None
    zip_file = zipfile.ZipFile(zipfilename)
    with open(dictionary, 'r') as f:
        for line in f.readlines():
            password = line.strip('\n')
            pwdList = []
            for start in range(len(password)):
                for index in range(500):
                    sub = password[start:index+1]
                    pwdList.append([sub, start, len(password)])
            p.map(openZip, pwdList)

if __name__ == '__main__':
    main()

我可能缺少一些琐碎的东西,但是我很难找到正确使用多重处理的方法。任何帮助将不胜感激。 :)

1 个答案:

答案 0 :(得分:1)

两件事-

1)进度指示器需要在多线程程序中重新考虑

有多个并行运行的线程。根据要调度的线程,将在stdout上显示print语句。因此,显示进度指示器的输出将全部混乱。由于您要跟踪每行字典的进度,因此可以考虑打印线程ID和进度指示器。最好是从当前线程正在处理的字典中打印行/密码。

另一种方法可能是打印从字典文件处理的行的总体进度。如果一个线程处理了词典文件的第7行,总共有10行。然后,当该线程完成时,可以显示70%的进度。请注意,此进度指示器的准确性将再次取决于线程的调度。线程处理行6可能会晚于7。这将首先显示70%,然后显示60%。可以通过存储最大行由线程处理并根据最大行显示进度。大概的进度就足够了。如果期望更高的准确性,那么它将变得更加复杂,您必须同步线程以捕获进度。

2)找到密码后退出整个过程

sys.exit()仅终止线程。对于退出过程,应使用os._exit或其他机制。