Python threading: дождитесь остановки потока, затем выполните функцию - PullRequest
0 голосов
/ 04 марта 2020

Я пытаюсь запустить функцию после завершения потока, но функция не вызывается. Структура кода:

class():

    def functiontocall()  # uses data calculated in thread for plotting. only works when thread is complete
        do something with self.A

    def watchthread():
        thread()
        functiontocall()
        # since this function depends on variable A, it throws an error.
        # I tried: if thread.join == True: functiontocall but this did not call the function.

    def thread():
        def run():
            pythoncom.CoInitialize()
            --- do stuff --
            for i in 1000:
                thousands of calculations while updating state in GUI ---
            A = result
            self.A = A
        thread = threading.Thread(target=run)
        thread.start()

примечание: я удалил 'self' для простоты.

thread.join должен сообщить мне, когда поток завершится, но по какой-то причине я все еще не могу запустить функциюtocall.

Это плохой способ организации потоков в целом?

Редактировать: я могу вызвать функцию после завершения потока, но не могу получить доступ к переменным, когда поток работает. например, 0-100% прогресса для индикатора прогресса в моем GUI. когда я использую:

def watchthread():
    thread()
    thread.join()
    functiontocall()

Я не могу обновить состояние потока в моем GUI. Он просто ждет окончания вычислений и запускает functiontocall ().

1 Ответ

0 голосов
/ 04 марта 2020

Поскольку вы используете потоки, после запуска потока Python перейдет к следующему, он не будет ждать окончания потока sh, пока вы не попросите об этом.

С вашим кодом, если вы хотите подождать, пока функция потока завершится sh, прежде чем двигаться дальше, это не звучит так, как будто вам нужна многопоточность, нормальная функция запустится, завершится, а затем Python перейдет к выполнению functiontocall ()

Если есть причина, по которой вам нужно использовать потоки, которые не встречаются в примере, я бы предложил использовать thread.join ()

threads = []  # list to hold threads if you have more than one
t = threading.Thread(target=run)
threads.append(t)

for thread in threads:  # wait for all threads to finish
    thread.join() 

functiontocall()  # will only run after all threads are done

Опять же, я бы предложил пересмотреть вопрос о том, нужно ли вам использовать потоки, поскольку это не кажется очевидным.

Чтобы обновить этот ответ на основе новой информации, возможно, вы хотите, чтобы переменная была доступна. В этом случае все потоки будут обновлять переменную вашего класса A, ваша функция GUI update также периодически читает это и обновляет вашу GUI.

class ThisClass():

    def __init__(self):
        self.A = 0

    def function_to_call(self):
        while self.A != 100:  # assuming this is a progress bar to 100%
            # update in GUI

    def run(self):
        # does calculations
        with lock: # to prevent issues with threads accessing variable at the same time
            self.A += calculations

    def progress(self):
        threads = []  # list to hold threads if you have more than one
        t = threading.Thread(target=run)
        threads.append(t)

        f = threading.Thread(target=self.function_to_call)
        threads.append(f)

        for thread in threads:
            thread.start()

        for thread in threads:  # wait for all threads to finish
            thread.join()
.
...