How does this while loop exit?

一笑奈何 提交于 2019-12-08 04:26:35

问题


So, how does this code exit the while statement when the thread is started? (Please do not consider indentation)

class ThreadUrl(threading.Thread):
    """Threaded Url Grab"""
    def __init__(self, queue, out_queue):
        threading.Thread.__init__(self)
        self.queue = queue
        self.out_queue = out_queue

    def run(self):
        while True:
            #grabs host from queue
            host = self.queue.get()

            #grabs urls of hosts and then grabs chunk of webpage
            url = urllib2.urlopen(host)
            chunk = url.read()

            #place chunk into out queue
            self.out_queue.put(chunk)

            #signals to queue job is done
            self.queue.task_done()

** EDIT *

The code that starts the thread:

def main():

#spawn a pool of threads, and pass them queue instance
    for i in range(5):
        t = ThreadUrl(queue)
        t.setDaemon(True)
        t.start()

    queue.join()

回答1:


It doesn't have to exit the while statement for the code to terminate. All that is happening here is that the thread has consumed everything in the queue at which point queue.join() returns.

As soon as the call to queue.join() in the main code returns the main code will exit and because you marked the thread as a daemon the entire application will exit and your background thread will be killed.




回答2:


The quick answer: it doesn't, unless an exception is raised anywhere, which depends on the functions/methods called in run.

Of course, there is the possibility, that your thread is suspended/stopped from another thread, which effectively terminates your while loop.




回答3:


Your code will only breaks if an exception occurs during the execution of the content of the while True loop.... not the better way to exit from a thread, but it could work.

If you want to exit properly from your thread, try to replace the while True with something like while self.continue_loop:

class ThreadUrl(threading.Thread):
    """Threaded Url Grab"""
    def __init__(self, queue, out_queue):
        threading.Thread.__init__(self)
        self.queue = queue
        self.out_queue = out_queue
        self.continue_loop = True

    def run(self):
        while self.continue_loop:
            #grabs host from queue
            host = self.queue.get()

            #grabs urls of hosts and then grabs chunk of webpage
            url = urllib2.urlopen(host)
            chunk = url.read()

            #place chunk into out queue
            self.out_queue.put(chunk)

            #signals to queue job is done
            self.queue.task_done()

And to start/stop the threads :

def main():

#spawn a pool of threads, and pass them queue instance
    threads = []
    for i in range(5):
        t = ThreadUrl(queue, out_queue)
        t.setDaemon(True)
        t.start()
        threads.append(t)

    for t in threads:
       t.continue_loop = False
       t.join()

    queue.join()



回答4:


You could pass in block=False or timeout=5 to your self.queue.get() method. This will raise an Queue.Empty exception if no items remains in the queue. Otherwise AFAIK, the self.queue.get() will block the whole loop so even additional break attempts further on would not be reached.

def run(self):
    while True:
        #grabs host from queue
        try:
            host = self.queue.get(block=False)
        except Queue.Empty, ex:
            break
        #grabs urls of hosts and then grabs chunk of webpage
        url = urllib2.urlopen(host)
        chunk = url.read()

        #place chunk into out queue
        self.out_queue.put(chunk)

        #signals to queue job is done
        self.queue.task_done()

Another approach would be to put a "Stop" flag in the queue after all your other items have been added. Then in the thread put a check for this stop flag and break if found.

Eg.

host = self.queue.get()
if host == 'STOP':
    #Still need to signal that the task is done, else your queue join() will wait forever
    self.queue.task_done()
    break


来源:https://stackoverflow.com/questions/7105371/how-does-this-while-loop-exit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!