简体   繁体   English

Python3 杀死一个被阻塞的线程

[英]Python3 kill a blocked Thread

So I am working on an task that can only be performed for an estimated total of 10 seconds.所以我正在处理一项估计总共只能执行 10 秒的任务。

I made a list of threading.Thread , that all access a queue.Queue to pull the tasks but after the 10 seconds are up I want to kill the threads and move on but, if I finish first I want to move on before 10 seconds.我制作了一个threading.Thread列表,所有这些都访问queue.Queue来拉任务,但是在 10 秒后我想杀死线程并继续前进,但是,如果我先完成,我想在 10 秒前继续前进.

I have a "manager" thread blocked on a call on queue.Queue this way I can see if the queue is complete before the 10 seconds are up.我有一个“管理器”线程在调用queue.Queue被阻塞,这样我就可以看到队列是否在 10 秒结束之前完成。

self._task_queue.join()

How can I have the main execution thread stop that thread if the timeout has been reached?如果已达到超时,如何让主执行线程停止该线程? Note I am using threading.Thread as the task these threads are doing is checking operating system tasks.注意我使用threading.Thread作为这些线程正在执行的任务是检查操作系统任务。

example:例子:

timeout_dt = datetime.utcnow() + timedelta(seconds=self._timeout) if self._timeout else None
while True:
    try:
        current_time = datetime.utcnow()
        if self._manager.event.is_set():
            logger.info(f'manager complete event {self._manager.event.is_set()}')
            break
        if timeout_dt and current_time > timeout_dt:
            logger.info(f'timeout complete current {current_time} timeout {timeout_dt}')
            # TODO: kill the manager thread waiting for queue.Queue.join()
            break
        time.sleep(1)
    except Exception as e:
        # An exception happened in the main execution thread
        logger.exception(e)

How I solved it我是如何解决的

class MyQueue(Queue):

    def timeout_join(self, timeout=None):
        '''Blocks until all items in the Queue have been gotten and processed.
        The count of unfinished tasks goes up whenever an item is added to the
        queue. The count goes down whenever a consumer thread calls task_done()
        to indicate the item was retrieved and all work on it is complete. If
        optional args 'timeout' is a non-negative number, it blocks at most
        'timeout' seconds and raises the TimeoutError exception if the number
        of unfinished tasks is not equal to the task_done in the available time.
        When the count of unfinished tasks drops to zero or timeout is reached,
        join() unblocks.
        '''
        with self.all_tasks_done:
            if timeout is None:
                while self.unfinished_tasks:
                    self.all_tasks_done.wait()
            elif timeout and timeout < 0:
                raise ValueError("'timeout' must be a non-negative number")
            else:
                endtime = time.time() + timeout
                while self.unfinished_tasks:
                    remaining = endtime - time.time()
                    if remaining <= 0.0:
                        raise TimeoutError
                    self.all_tasks_done.wait(remaining)

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

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