简体   繁体   中英

Python3 kill a blocked Thread

So I am working on an task that can only be performed for an estimated total of 10 seconds.

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.

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.

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.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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