grepword- py main thread thread # thread # thread # figure multithreaded program getting the user' options and the file list are the same as before once we have the necessary information we create queue queue and then loop as many times as there are threads to be createdthe default is for each thread we prepare number string for debugging (an empty string if we are not debuggingand then we create worker ( threading thread subclassinstance--we'll come back to setting the daemon property in moment next we start off the threadalthough at this point it has no work to do because the work queue is emptyso the thread will immediately be blocked trying to get some work with all the threads created and ready for work we iterate over all the filesadding each one to the work queue as soon as the first file is added one of the threads could get it and start on itand so on until all the threads have file to work on as soon as thread finishes working on file it can get another oneuntil all the files are processed notice that this differs from grepword- py where we had to allocate slices of the file list to each child processand the child processes were started and given their lists sequentially using threads is potentially more efficient in cases like this for exampleif the first five files are very large and the rest are smallbecause each thread takes on one job at time each large file will be processed by separate threadnicely spreading the work but with the multiple processes approach we took in the grepword- py programall the large files would be given to the first process and the small files given to the othersso the first process would end up doing most of the work while the others might all finish quickly without having done much at all the program will not terminate while it has any threads running this is problem because once the worker threads have done their workalthough they have finished they are technically still running the solution is to turn the threads into daemons the effect of this is that the program will terminate as soon as the program has no nondaemon threads running the main thread is not daemonso once the main thread finishesthe program will cleanly terminate each daemon thread and then terminate itself of coursethis can now create the opposite problem--once the threads are up and running we must ensure that the main thread does not finish until all the work is done this is achieved by calling queue queue join()--this method blocks until the queue is empty here is the start of the worker class