Another basic point to remember about threads, is that a thread needs to reach the end of it's code block, or return, before it can be joined. Also a detached thread needs to return, or reach code end, before it will succesfully close. If you don't account for this, you get the error "a thread closed while x number were still running". This is harmless, but it is caused by threads not returning, before the main program exits.
If your threads are running loops that don't have a definite completion point, you can used shared variables, to signal it to drop what it's doing, and return immediately.