A more elegant way to interrupt time.sleep in python-event.wait

Scenario description:

Realize a function, start a thread, as long as the thread is not interrupted, it will always be while true, accumulating a certain number intermittently for 10s;

When the thread thread signals, the while stops and the thread exits.

1. Method one time.sleep

import time
from threading import Thread


class AddTask(Thread):

    def __init__(self):
        super().__init__()
        self.sum_num = 0
        self._button = True

    def run(self):
        print('Begin to add ...')
        while self._button:
            print('Sleep start...')
            time.sleep(10)
            print('Sleep end...')
            self.sum_num += 10
        print(f"Finish add, sum:{self.sum_num}...")

    def stop(self):
        print('Stop task...')
        self._button = False


def do_main_task():
    print('Do main task...')
    time.sleep(15)
    print('Finish main task...')
    return True


if __name__ == '__main__':
    add_task = AddTask()
    add_task.start()
    main_task_end = do_main_task()
    if main_task_end:
        add_task.stop()
        time.sleep(1)
        print(f"sum: {add_task.sum_num}")

Results of the:

Begin to add ...Do main task...
Sleep start...
Sleep end...
Sleep start...
Finish main task...
Stop task...
sum: 10
Sleep end...
Finish add,sum: 20...

Explain what this code means. Inside the main thread, I call do_main_task ()to trigger a task. This task will take longer to execute (15s is set here). But after this task is completed, there will be a return value telling me that it is completed. In addition, create an add_task sub-thread, adding 10 every 10 seconds.

But in some cases, I don't need to wait, for example, the user actively canceled the task. At this time, I want to end this add_task sub-thread early.

It can be seen from the execution results that when +10 is executed once, after waiting for 10s, and after another 5 seconds, the main thread do_main_task ends, and the add_task thread is still in the accumulated sleep (10) and has not exited. The execution result of the main thread is already sum=10, and the add_task thread will end after another 5 seconds.

However, the thread cannot be actively killed from the outside, it can only be allowed to exit by itself.

2. Method 2 event.wait

应用threadinginside the moduleEvent,

用法和sleep差不多:

import threading

event = threading.Event()
event.wait(5)

The above example can be implemented like this:

import time
from threading import Thread
from threading import Event


class AddTask(Thread):

    def __init__(self):
        super().__init__()
        self.sum_num = 0
        self.event = Event()

    def run(self):
        print('Begin to add ...')
        while not self.event.is_set():
            print('Sleep start...')
            self.event.wait(10)
            print('Sleep end...')
            self.sum_num += 10
        print(f"Finish add, sum:{self.sum_num}...")

    def stop(self):
        print('Stop task...')
        self.event.set()


def do_main_task():
    print('Do main task...')
    time.sleep(15)
    print('Finish main task...')
    return True


if __name__ == '__main__':
    add_task = AddTask()
    add_task.start()
    main_task_end = do_main_task()
    if main_task_end:
        add_task.stop()
        time.sleep(1)
        print(f"sum: {add_task.sum_num}")

Results of the:

Do main task...
Begin to add ...
Sleep start...
Sleep end...
Sleep start...
Finish main task...
Stop task...
Sleep end...
Finish add, sum:20...

sum: 20

When executed event.set(), False will be returned in the child thread self.event.is_set(), so the loop will not continue to execute.

即使self.event.wait(10)Just started blocking, as long as I execute it in the main thread event.set(), the blocking in the sub-thread will end immediately. So the child thread will end immediately. No need to wait 10 seconds in vain.

Moreover, event.wait()this function is implemented in C language at the bottom, without interference from GIL locks.

 

Guess you like

Origin blog.csdn.net/qq_19446965/article/details/126793548