调用函数时结束该线程的最佳方法是什么?

发布于 2024-11-04 11:56:28 字数 577 浏览 11 评论 0原文

我在使用这个队列时遇到了一些麻烦:

import Queue
import threading

class test(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.request_queue = Queue.Queue()

    def addtoqueue(self, item):
        self.request_queue.put(item)

    def run(self):
        while True:
            item = self.request_queue.get(True)
            print item

这个简单的类实现了一个线程队列。调用 test::addtoqueue 会将一个项目追加到队列中。该线程等待一个项目被添加到队列中 - 并立即打印它并等待下一个项目。

我的问题是应用程序关闭。终止线程的最佳方法是什么?我可以使用条件,但如何等待来自条件的通知或队列中的新项目?

I'm having a bit of trouble with this queue:

import Queue
import threading

class test(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.request_queue = Queue.Queue()

    def addtoqueue(self, item):
        self.request_queue.put(item)

    def run(self):
        while True:
            item = self.request_queue.get(True)
            print item

This simple class implements a threaded queue. Calling test::addtoqueue will append an item to the queue. The thread waits for an item to be added to the queue - and immediately prints it and waits for the next thing.

My problem is application shutdown. What is the best way to terminate the thread? I could use a Condition, but how could I wait for either a notification from the Condition or a new item in the queue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

帅气尐潴 2024-11-11 11:56:28

你可以向线程发送一些毒药来杀死它:

poison = None # something you wouldn't normally put in the Queue

class test(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.request_queue = Queue.Queue()

    def kill(self):
        self.addtoqueue(poison)

    def addtoqueue(self, item):
        self.request_queue.put(item)

    def run(self):
        while True:
            item = self.request_queue.get(True)
            if item is poison:
                # do stuff
                return # end thread
            print item

You can send some poison to the thread to kill it:

poison = None # something you wouldn't normally put in the Queue

class test(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.request_queue = Queue.Queue()

    def kill(self):
        self.addtoqueue(poison)

    def addtoqueue(self, item):
        self.request_queue.put(item)

    def run(self):
        while True:
            item = self.request_queue.get(True)
            if item is poison:
                # do stuff
                return # end thread
            print item
浮华 2024-11-11 11:56:28

我会改变 while 循环中的条件,以便它检查局部变量。添加终止开关以允许外部进程关闭线程。您可能应该扩展kill_me 以一种好的方式处理对象及其队列(例如,如果您想存储队列以供下次运行)。

编辑我还在其中添加了一个has_finished变量,因此kill_me应该阻止主进程线程。这应该允许线程在返回到主流程之前退出。

我可能把事情搞得太复杂了;)

class test(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.request_queue = Queue.Queue()
        self.is_running = True
        self.has_finished = False   

    def addtoqueue(self, item):
        self.request_queue.put(item)

    def kill_me(self):
        self.is_running = False
        while not self.has_finished:
            pass

    def run(self):
        while self.is_running:
            item = self.request_queue.get(True)
            print item
        self.has_finished = True

I'd alter the condition in your while loop so that it checked for a local variable. Add add a kill-switch to allow an external process to shut the thread down. You should probably extend kill_me to dispose of the object and its Queue in a nice way (eg if you want to store the Queue for the next time it's run).

Edit I've also added a has_finished variable in there so kill_me should block the main process thread. This should allow the thread to exit before handing back to the main flow.

I may have overcomplicated things ;)

class test(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.request_queue = Queue.Queue()
        self.is_running = True
        self.has_finished = False   

    def addtoqueue(self, item):
        self.request_queue.put(item)

    def kill_me(self):
        self.is_running = False
        while not self.has_finished:
            pass

    def run(self):
        while self.is_running:
            item = self.request_queue.get(True)
            print item
        self.has_finished = True
明月夜 2024-11-11 11:56:28

做可能有效的最简单的事情 - 在这种情况下,可能是哨兵。尽管threading受到Java线程库的启发,但在Python中,最简单的事情不是像Java一样做事情并继承threading.Thread,而是传递一个函数及其threading.Thread() 的参数:

DONE = object() # Sentinel

def run(queue):
    while True:
        item = queue.get()
        queue.task_done()
        if item is DONE:
            break
        print item

request_queue = Queue.Queue()
some_thread = Thread(target=run, args=(request_queue,))

some_thread.start()

request_queue.put('hey')
request_queue.put('joe')
request_queue.put(DONE)

Do The Simplest Thing That Could Possibly Work - which, in this case, might be a Sentinel. And although threading was inspired by Java's threading library, in Python the simplest thing is not do things Java-like and inherit from threading.Thread, but to pass a function and its arguments to threading.Thread():

DONE = object() # Sentinel

def run(queue):
    while True:
        item = queue.get()
        queue.task_done()
        if item is DONE:
            break
        print item

request_queue = Queue.Queue()
some_thread = Thread(target=run, args=(request_queue,))

some_thread.start()

request_queue.put('hey')
request_queue.put('joe')
request_queue.put(DONE)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文