简体   繁体   English

while循环如何退出?

[英]How does this while loop exit?

So, how does this code exit the while statement when the thread is started? 那么,该代码如何在线程启动时退出while语句? (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()

It doesn't have to exit the while statement for the code to terminate. 它不必退出while语句即可终止代码。 All that is happening here is that the thread has consumed everything in the queue at which point queue.join() returns. 这里发生的所有事情是线程已经消耗了队列中的所有内容,这时queue.join()返回。

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. 在主代码中对queue.join()的调用返回后,主代码将立即退出,并且由于您将该线程标记为守护程序,因此整个应用程序将退出,并且后台线程将被杀死。

The quick answer: it doesn't, unless an exception is raised anywhere, which depends on the functions/methods called in run . 快速答案:不会,除非在任何地方引发异常,这取决于在run调用的函数/方法。

Of course, there is the possibility, that your thread is suspended/stopped from another thread, which effectively terminates your while loop. 当然,您的线程可能会从另一个线程挂起/停止,从而有效地终止了while循环。

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. 仅当执行while True循环的内容期间发生异常时,您的代码才会中断。....不是退出线程的更好方法,但是它可以工作。

If you want to exit properly from your thread, try to replace the while True with something like while self.continue_loop: 如果要从线程中正确退出,请尝试将while True替换为while self.continue_loop:类的东西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()

You could pass in block=False or timeout=5 to your self.queue.get() method. 您可以将block = False或timeout = 5传递给self.queue.get()方法。 This will raise an Queue.Empty exception if no items remains in the queue. 如果队列中没有剩余项目,则将引发Queue.Empty异常。 Otherwise AFAIK, the self.queue.get() will block the whole loop so even additional break attempts further on would not be reached. 否则AFAIK,self.queue.get()将阻塞整个循环,因此甚至无法进行进一步的中断尝试。

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. 另一种方法是在添加了所有其他项目之后,将“ Stop”标志放入队列中。 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM