start_new_thread класса внутри start_new_thread

#python #python-2.7

#python #python-2.7

Вопрос:

Я пытаюсь использовать start_new_thread внутри другого start_new_thread .

Теперь приблизительный макет кода выглядит следующим образом

Main.py

 ....
a = Helper()
start_new_thread(a.x,()) # 1 
....
  

Внутренний вспомогательный класс

 ....
def x(self):
    start_new_thread(self.a,()) # 2
....
  

Эти функции намеренно не являются потокобезопасными.
Проблема в том, что всякий раз, когда #2 выполняется, он временно останавливает основной поток, пока он не будет возвращен.

Почему это происходит и что можно сделать, чтобы преодолеть это?

Комментарии:

1. В Python используется глобальная блокировка интерпретатора (GIL) . В любой момент времени будет выполняться только один поток.

2. Что, если нет выхода из многопоточности, и я должен использовать все эти потоки одновременно?

Ответ №1:

Я думаю, вам пора прочитать о GIL.

Комментарии:

1. Бывает так, что функции не могут быть удалены из потоков. Эти потоки необходимы, поскольку работа связана с сетью. Удаление потоков приведет к зависанию основного процесса, что вообще нежелательно

2. Сетевой ввод-вывод является одним из исключений, когда освобождается GIL. Но вы все равно можете выполнять сетевые операции без потоков, используя что-то вроде twisted , gevent , greenlet или select для стандартной библиотеки . Также у вас будет более высокая производительность в случае одновременной обработки большого количества подключений.

Ответ №2:

 class KThread(threading.Thread):

 def __init__(self, *args, **kwargs):

    threading.Thread.__init__(self, *args, **kwargs)
    self.killed = False

 def start(self):

    self.__run_backup = self.run
    self.run = self.__run      # Force the Thread to install our trace.
    threading.Thread.start(self)

 def __run(self):

    sys.settrace(self.globaltrace)
    self.__run_backup()
    self.run = self.__run_backup

 def globaltrace(self, frame, why, arg):
    if why == 'call':
      return self.localtrace
    else:
      return None

 def localtrace(self, frame, why, arg):
    if self.killed:
      if why == 'line':
        raise SystemExit()
    return self.localtrace

 def kill(self):

    self.killed = True

 ###################################

class 2:
 t2 = KThread(target=function)
 t2.start()
 t2.kill()
 t3 = KThread(target=function)
 t3.start()
 t3.kill()