Python - Создание threading.thread, чтобы не ждать выполнения других потоков и зацикливаться вечно - PullRequest
0 голосов
/ 29 ноября 2018

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

def test(name):
    while True:
          print(name)
          time.sleep(1)   



def main():
    try:
        random_names = []
        for names in [line.rstrip('\n') for line in open('name.txt')]:
            random_names.append(names)

        threads = []
        for name in random_names:
            p = threading.Thread(target=test, args=(name,))
            threads.append(p)
            p.start()

        for thread in threads:
            thread.join()

    except KeyboardInterrupt:
        print('Keyboard - Interrupted')
        sys.exit()

В основном я только что создал случайный текстовый файл, который содержит 100 имен (полностью случайный)где моя цель состоит в том, чтобы в каждом потоке была запущена определенная нить.

Теперь есть кое-что, что я совсем не понял.Я предполагаю, что с помощью thread.join, когда работает 100 потоков.Всякий раз, когда один из них сделан, он будет в основном ждать, пока все остальное будет сделано, если я прав?

Это подводит меня к вопросу два: если вы не хотите, чтобы это произошло, и вы просто хотите запустить«поток для себя» означает, что всякий раз, когда один из потоков выполняется, вместо того, чтобы ждать, он должен просто продолжать работать снова, вместо того, чтобы ждать запуска остальных потоков?

И мой последний вопрос:каким образом можно было бы сделать так, чтобы потоки работали вечно в этом случае?Я предполагаю, что этот код, который я сейчас использую, может быть исправлен сейчас, так как я использую , в то время как True: , но это допустимо, и это будет означать, что thread.join даже не будет затронут, если некоторое время True будет работать снова и снова в def test ()?

1 Ответ

0 голосов
/ 29 ноября 2018

Каждый поток будет работать полностью независимо от других (кроме тех случаев, когда вы создаете взаимозависимости).Таким образом, если вы создаете 100 потоков, и потоки не нуждаются в каком-либо взаимодействии с другими потоками, и один из них завершает работу ( т.е. завершается, возвращаясь из своей целевой функции), другие 99 не затрагиваются и будут простопродолжать бежать.

thread.join заставляет вызывающий поток ожидать завершения одного целевого потока.В отсутствие тайм-аута или какого-либо другого внешнего фактора он будет ждать forever для завершения целевого потока.На join не влияет ни один поток , кроме целевого потока.Другими словами, если вы пытаетесь присоединиться к потоку 1 и выход из потока 2, это не приведет к тому, что ваш join из потока 1 завершится рано или поздно.

В вашем коде ваши потокивсе выполняют while True, что означает, что никто из них никогда не вернется из своей целевой функции и, следовательно, никогда не "завершит".Это означает, что ваш основной поток будет зависать при первом вызове thread.join навсегда.Это совершенно справедливо для ваших 100 потоков, чтобы все выполнялись вечно, если это то, что вы хотите.

Аналогично, ваш основной поток может назвать join таким образом.Но, конечно, основной поток может продолжать выполнять и другую работу.И если вы не ожидаете, что другие потоки завершат работу, для основного потока не требуется вызывать join.Он может просто вернуться (фактически завершиться).Другие потоки и сама ваша программа будут продолжать работать.

Или вы можете даже создать 99 дополнительных потоков и включить основной поток и вызвать вашу функцию test как сотую.(Это, конечно, усложнит логику вашего чистого цикла чтения-строки-начала-потока, так что я бы на самом деле не рекомендовал это.)

То, как вы это делаете, теперь кажется идеальным.Поскольку у есть ожидание основного потока в join (даже если join никогда не завершится), ваш обработчик исключений KeyboardInterrupt остается в области видимости в основном потоке, так что ваша программа завершается корректнона Ctrl-C (sys.exit убивает весь процесс, и, следовательно, все потоки прекращаются).

EDIT:Очевидно, sys.exit делает , а не завершает весь процесс - только поток, в котором он выполняется.Вам нужно будет использовать os._exit из обработчика KeyboardInterrupt для корректного выхода (или сначала остановить каждый поток).

...