Я совсем недавно начал изучать, как писать многопоточные программы на python, и для начала начал экспериментировать без с использованием очередей.
В приведенном ниже коде loadFunction - это просто пример целевой функции для потоков. предполагается , чтобы дождаться завершения всех потоков, представленных в аргументе wait (list), (и я пытаюсь добиться этого с помощью join ()). Затем , затем , начинают распечатывать указанный диапазон номеров.
Это желаемое поведение.
В основной программе я создал два потока, которые не ожидают, пока другие потоки начнут считать. Затем я создал третий поток, который должен дождаться завершения первых двух потоков, прежде чем начнется его подсчет.
Однако этого не происходит. При тестировании я обнаружил, что три потока начинают выполняться одновременно, а третий поток не ждет, пока первые два не завершат выполнение, как я планировал.
Итак, мой вопрос здесь: какие знания мне не хватает в функции Thread.join () и какие изменения я могу внести в свой код для достижения желаемого результата?
Код:
""" Note: Python 3.3 onwards required since daemon was added as an initializable
property from python 3.3 onwards."""
import threading
def loadFunction(name, start, end, wait=[]):
""" wait should be a list of threads to wait for """
map(lambda th: th.join(), wait)
for number in range(start, end):
print("%s : %d" % (name, number))
if __name__ == "__main__":
t1 = threading.Thread(target=loadFunction, args=("Thread1", 1, 101), name="Thread1" ,daemon=True)
t2 = threading.Thread(target=loadFunction, args=("Thread2", 101, 201), name="Thread2", daemon=True)
t3 = threading.Thread(target=loadFunction, args=("Thread3", 1000, 1101, [t1, t2]), name="Thread3", daemon=True)
t1.start()
t2.start()
t3.start()
# wait for all of the daemon processes to finish before we close the program
t1.join()
t2.join()
t3.join()
print("done!")
часть результата (за один проход):
Thread1 : 1
Thread1 : 2
Thread1 : 3
Thread1 : 4
Thread1 : 5
Thread1 : 6
Thread2 : 101
Thread2 : 102
Thread2 : 103
Thread2 : 104
Thread2 : 105
Thread2 : 106
Thread2 : 107
Thread2 : 108
Thread2 : 109
Thread1 : 7
Thread1 : 8
Thread1 : 9
Thread1 : 10
Thread1 : 11
Thread3 : 1000
Thread1 : 12
Thread1 : 13
Thread3 : 1001
Thread1 : 14
Thread3 : 1002
Thread1 : 15
Thread3 : 1003
Thread1 : 16
Thread2 : 110
Вот две вещи, которые приходили мне в голову, когда я писал этот код (как указано в официальной документации ):
присоединитесь (таймаут = None)
Дождитесь окончания потока. Это блокирует вызов
поток, пока поток, чей метод join () вызывается, не завершится ...
Что касается моего примера кода, будет ли "вызывающий поток" быть тем потоком, который вызвал функцию loadFunction? У меня есть небольшое подозрение, что это не тот случай, и что сам процесс вызвал функцию, а не поток, следовательно, поток не будет тем, кто ожидает, но процесс ждет вместо. Если это так, как бы я это исправить? У меня такое ощущение, что очереди будут вовлечены ... , если это причина, в первую очередь.
и
Нить можно присоединить () к много раз.
- вот что заставляет меня дважды использовать join для одной и той же темы.
P.S. Я впервые изучаю многопоточность в Python, но это после изучения процессов разветвления в C, так что, возможно, я мог бы запутаться здесь из-за этого. Если эти два понятия не связаны, то я извиняюсь, у меня сложилось впечатление, что оба они похожи (хотя, очевидно, не то же самое, поскольку один разделяет процесс, а другой создает потоки внутри самого процесса).
Спасибо.