Reputation: 315
So I am trying to figure out how threading more and more and I just made a simple script that looks like:
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()
Basically I just created random text file that contains 100 names (Totally random) where my goal are that each thread will have a given thread running for it.
Now there is something I quite didn't get a grip off. I assume using thread.join is that when there is 100 threads running. Whenever 1 of them are done, it will wait basically until the rest are done if I am correct?
That takes me to question two: If you don't want it to happend and you basically just want to run the threading "for itself" meaning that whenever one of the thread is done, instead of waiting it should just continue to work again instead of waiting for the rest of threads to run?
And to my final question is, in which way would it possible to make it so the threads are running forever in that case? I assume that this code I am using now might be the fix now since I am using a while True: but is that a valid thing to do and will that mean that the thread.join will not even be touched if there is a while True running over and over in the def test()?
Upvotes: 1
Views: 2216
Reputation: 12357
Each thread will run completely independent of the others (except as you create interdependencies). So if you create 100 threads, and the threads don't need any interaction from other threads, and one of them completes (i.e. exits by returning from its target function), the other 99 are unaffected and will just continue to run.
thread.join
causes the calling thread to wait until the single target thread completes. In the absence of a timeout or some other outside factor, it will wait forever for the target thread to complete. The join
is unaffected by any thread other than the target thread. In other words, if you're attempting to join thread 1, and thread 2 quits, that will not cause your join
of thread 1 to complete any sooner or later.
In your code, your threads are all executing a while True
, which means none of them will ever return from their target function and hence will never "complete". That means your main thread will hang on the first thread.join
call forever. It's perfectly valid for your 100 threads to all execute forever if that is what you wish.
Likewise, it's fine for your main thread to call join
like that. But of course, the main thread could go on to do other work as well. And if you don't expect the other threads to exit, there's no requirement for the main thread to call join
. It could simply return (in effect, completing itself). The other threads and your program itself will happily continue to execute.
Or, you could even create 99 additional threads and have the main thread join in and call your test
function as the 100th. (This would of course complicate the logic of your clean read-a-line-start-a-thread loop so I wouldn't actually recommend that.)
The way you have it now seems ideal. Because you are having the main thread wait in the join
(even though the join
will never complete), your KeyboardInterrupt
exception handler remains in scope in the main thread so that your program terminates cleanly on Ctrl-C (sys.exit
kills the entire process, and hence all the threads are terminated).
EDIT:
Apparently, sys.exit
does not terminate the entire process -- only the thread in which it executes. You would need to use os._exit
from the KeyboardInterrupt
handler to exit cleanly (or stop each of the threads first).
Upvotes: 1