Для начала скажи, какую задачу ты пытаешься решить.
Для случая с одноразовым потоком-воркером, тебе не нужна глобальная переменная. Достаточно класса.
import threading
class MyWorkerThread(threading.Thread):
def __init__(self, arg1: float, arg2: float): # передаём потоку входные данные
# поток не должен их менять!
super().__init__()
self.arg1 = arg1
self.arg2 = arg2
self.result: t.Optional[float] = None
def run(self):
time.sleep(10) # имитируем длительную работу
self.result = self.arg1 + self.arg2
И тогда ты можешь его использовать так:
worker = MyWorkerThread(42, 69)
worker.start()
while True:
if worker.is_alive(): # проверяем, жив ли поток
# делаешь ещё что-то, пока поток работает
print('Still working...')
time.sleep(0.5)
else:
# поток завершился, даём знать пользователю.
print(f'Done! Result is {worker.result}!')
break # выходим из цикла
Если же тебе нужно просто дождаться конца потока, ничего не делая в процессе, можно сделать просто
worker.join()
Сложности начинаются, когда тебе нужно взаимодействовать с длительным потоком. Усложним пример:
import threading, queue
class MyWorkerThread(threading.Thread):
def __init__(self, arg1: float, arg2: float): # передаём потоку входные данные
# поток не должен их менять!
super().__init__()
self.arg1 = arg1
self.arg2 = arg2
self.result: t.Optional[float] = None
self.progress = queue.Queue()
def run(self):
for i in range(10):
time.sleep(1) # имитируем длительную работу
self.progress.put(i/10) # сообщаем о прогрессе
self.result = self.arg1 + self.arg2
self.progress.put(1.00)
Тогда код использования изменится следующим образом:
worker = MyWorkerThread(42, 69)
worker.start()
while True:
if worker.is_alive(): # проверяем, жив ли поток
# делаешь ещё что-то, пока поток работает
try:
progress = worker.progress.get(block=True, timeout=0.5)
except queue.Empty: # поток ничего не сообщил
print('Still working...')
else:
print(f'Still working... {progress:.0%}')
worker.progress.task_done() # один вызов task_done() на один успешный вызов get()!
else:
# поток завершился, даём знать пользователю.
print(f'Done! Result is {worker.result}!')
break # выходим из цикла
Если тебе нужно передать потоку новые задания, то можешь использовать ещё одну queue.