<div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="gmail_quote"><div class="im"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="gmail_quote"><div>Only really glanced at this, but you seem to be checking only the last thread *after* the loop? Surely you should be storing all the threads in a list (or someplace) as you create them, and then check them all for liveness and if so join them each in turn, to ensure you only print 'FINISHED' once you've checked and confirmed that all the threads created have in fact finished.<br>
<br>Walter<br></div></div><br></blockquote><div><br></div></div><div>That makes absolute sense. Doh on my part!<br><br>Thanks! </div></div><br>
</blockquote></div><br><div>Just done a little more reading and came across this in an O'Reilly article here <a href="http://www.oreillynet.com/onlamp/blog/2008/01/pymotw_threading.html">http://www.oreillynet.com/onlamp/blog/2008/01/pymotw_threading.html</a></div>
<div><br></div><div>Seems like an elegant way to accomplish a wait until all running threads have finished.</div><div><br></div><div><p style="margin-bottom: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; ">
<span style="font-weight: bold; ">Using enumerate() to wait for all running threads:</span></p><p style="margin-bottom: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; ">It is not necessary to retain an explicit handle to all of the daemon threads you start in order to ensure they have completed before exiting the main process. <code style="color: rgb(0, 51, 102); font-family: 'Andale Mono', 'Courier New', Courier, monospace; ">threading.enumerate()</code>returns a list of active <code style="color: rgb(0, 51, 102); font-family: 'Andale Mono', 'Courier New', Courier, monospace; ">Thread</code> instances. The list includes the current thread, and since joining the current thread is not allowed (it introduces a deadlock situation), we must check before joining.</p>
<p style="margin-bottom: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; "><br></p><p style="margin-bottom: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; "></p><pre style="clear: both; overflow-x: auto; overflow-y: auto; background-color: rgb(239, 239, 239); font-size: 12px; padding-top: 2px; padding-right: 2px; padding-left: 2px; padding-bottom: 1.5em; width: 586px; ">
<span class="k">import</span> <span class="nn">random</span>
<span class="k">import</span> <span class="nn">threading</span>
<span class="k">import</span> <span class="nn">time</span>
<span class="k">def</span> <span class="nf">worker</span><span class="p">():</span>
<span class="sd">"""thread worker function"""</span>
<span class="n">t</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">currentThread</span><span class="p">()</span>
<span class="n">pause</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">5</span><span class="p">)</span>
<span class="k">print</span> <span class="s">'Starting:'</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">getName</span><span class="p">(),</span> <span class="s">'sleeping'</span><span class="p">,</span> <span class="n">pause</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="n">pause</span><span class="p">)</span>
<span class="k">print</span> <span class="s">'Ending :'</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">getName</span><span class="p">()</span>
<span class="k">return</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">3</span><span class="p">):</span>
<span class="n">t</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">worker</span><span class="p">)</span>
<span class="n">t</span><span class="o">.</span><span class="n">setDaemon</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
<span class="n">t</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">main_thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">currentThread</span><span class="p">()</span>
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">threading</span><span class="o">.</span><span class="n">enumerate</span><span class="p">():</span>
<span class="k">if</span> <span class="n">t</span> <span class="ow">is</span> <span class="n">main_thread</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">print</span> <span class="s">'Joining :'</span><span class="p">,</span> <span class="n">t</span><span class="o">.</span><span class="n">getName</span><span class="p">()</span>
<span class="n">t</span><span class="o">.</span><span class="n">join</span><span class="p">()</span></pre><p></p></div>