Каждый поток будет работать полностью независимо от других (кроме тех случаев, когда вы создаете взаимозависимости).Таким образом, если вы создаете 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
для корректного выхода (или сначала остановить каждый поток).