#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()