2017-01-13 3 views
0

Я просто портировал скрипт с помощью библиотеки multithreading в библиотеку multiprocessing, поэтому я сталкиваюсь с проблемами, связанными с тем, как память распределяется между процессами.Многопроцессорный цикл и условие остановки

Краткий обзор, мои работники потребляют очередь слов; когда работник находит удар, он должен boradcast сигнал (глобальная переменная или любая реализация), чтобы упорядочить остальные запущенные процессы для завершения.

Вот основной метод моих работников:

def run(self): 
    while not self.queue.empty(): 
     entry = self.queue.get() 

     try: 
      payload = jwt.decode(self.token, entry, algorithm = 'HS256') 
     except jwt.InvalidTokenError: 
      if self.verbose: 
       print(DEBUG + "[{}] ".format(self.name) + "InvalidTokenError: " + Style.BRIGHT + entry + RESET) 
      continue 
     except jwt.DecodeError: 
      print(WARNING + "[{}] ".format(self.name) + "DecodingError: " + Style.BRIGHT + entry + RESET) 
      continue 
     except Exception as ex: 
      print(ERROR + "[{}] ".format(self.name) + "Exception: " + Style.BRIGHT + "{}".format(ex) + RESET) 
      continue 

     # Save the holy secret into a file in case sys.stdout is not responding 
     with open("jwtpot.pot", "a+") as file: 
      file.write("{0}:{1}:{2}".format(self.token, payload, entry)) 
      print(RESULT + "[{}] ".format(self.name) + "Secret key saved to location: " + Style.BRIGHT + "{}".format(file.name) + RESET) 

     print(RESULT + "[{}] ".format(self.name) + "Secret key: " + Style.BRIGHT + entry + RESET) 
     print(RESULT + "[{}] ".format(self.name) + "Payload: " + Style.BRIGHT + "{}".format(payload) + RESET) 

     break 

     self.queue.task_done() 

Вот как я создание экземпляра и начать свои процессы в моем основном:

# Load and segmentate the wordlist into the queue 
      print(INFO + "Processing the wordlist..." + RESET) 
      queue = populate_queue(queue, wordlist, verbose) 

      print(INFO + "Total retrieved words: " + Style.BRIGHT + "{}".format(queue.qsize()) + RESET) 

      for i in range(process_count): 
       process = Process(queue, token, verbose) 
       process.daemon = True 
       print(INFO + "Starting {}".format(process.name) + RESET) 
       process.start() 
       processes.append(process) 

      print(WARNING + "Pour yourself some coffee, this might take a while..." + RESET) 

      # Block the parent-process until all the child-processes finish to process the queue 
      for process in processes: 
       process.join() 

ответ

0

Я хотел бы создать (общие) трубы от всех подпроцессы возвращаются к родительскому. Затем процесс, который находит секретный ключ, может написать что-то в трубку, чтобы указать, что было найдено. Если процесс не находит секретный ключ, а очередь пуста, он просто выходит.

Родитель просто ждет, пока он не вернется из трубы, что произойдет либо при записи ребенком в трубу, либо при выходе всех детей. Затем он убивает всех оставшихся детей, которые все еще работают.

Вот быстрый хак демонстрирующий:

from multiprocessing import * 
from time import sleep 

def process(pid, rpipe, wpipe): 
    rpipe.close() 
    sleep(1 + pid * 0.1) 
    if pid == 5: 
     print("I found it!") 
     wpipe.send((pid, "GOT IT")) 
    print("Process %d exiting" % pid) 
    wpipe.close() 

def one_try(findit): 
    processes = [] 
    rpipe, wpipe = Pipe() 

    for i in range(15): 
     # Start 
     if i != 5 or findit: 
      p = Process(target=process, args=(i, rpipe, wpipe)) 
      p.start() 
      processes.append((i, p)) 

    # Close write pipe in the parent so we get EOF when all children are gone 
    wpipe.close() 
    try: 
     pid, result = rpipe.recv() 
     print("%s was found by %s" % (result, pid)) 
     print("Will kill other processes") 
    except EOFError: 
     print("Nobody found it!") 
    rpipe.close() 

    for i, p in processes: 
     p.terminate() 
     p.join() 

one_try(True)  # Should have one process that finds it 
one_try(False)  # Nobody found it 
Смежные вопросы