time sleep(((numproducers- nummessages print('main thread exit 'before show you this script' outputi want to highlight few points in its code arguments versus globals notice how the queue is assigned to global variablebecause of thatit is shared by all of the spawned threads (all of them run in the same process and in the same global scopesince these threads change an object instead of variable nameit would work just as well to pass the queue object in to the threaded functions as an argument--the queue is shared object in memoryregardless of how it is referenced (see queuetest py in the examples tree for full version that does this)dataqueue queue queue(shared objectinfinite size def producer(idnumdataqueue)for msgnum in range(nummessages)time sleep(idnumdataqueue put('[producer id=%dcount=% ](idnummsgnum)def consumer(idnumdataqueue)if __name__ ='__main__'for in range(numproducers)thread start_new_thread(producer(idataqueue)for in range(numproducers)thread start_new_thread(producer(idataqueue)program exit with child threads also notice how this script exits when the main thread doeseven though consumer threads are still running in their infinite loops this works fine on windows (and most other platforms)--with the basic _thread modulethe program ends silently when the main thread does this is why we've had to sleep in some examples to give threads time to do their workbut is also why we do not need to be concerned about exiting while consumer threads are still running here in the alternative threading modulethoughthe program will not exit if any spawned threads are runningunless they are set to be daemon threads specificallythe entire program exits when only daemon threads are left threads inherit default initial daemonic value from the thread that creates them the initial thread of python program is considered not daemonicthough alien threads created outside this module' control are considered daemonic (including some threads created in codeto override inherited defaultsa thread object' daemon flag can be set manually in other wordsnondaemon threads prevent program exitand programs by default do not exit until all threading-managed threads finish parallel system tools