简体   繁体   中英

Interrupting Infinite Loop in Threading

I am learning about threading using Python 3.8.2. I have one function with an infinite loop, and then two other functions that use the threading.Timer class.

def x:
    while True:
        dosomething()

def f1():
    dosomething2()
    threading.Timer(60,f1).start()

def f2():
    dosomething3()
    threading.Timer(100,f2).start()

Then I start three threads:

t1 = threading.Thread(target=x)
t2 = threading.Thread(target=f1)
t3 = threading.Thread(target=f2)

When it comes time to execute the f1 or f2, I don't want the x() to be executing at the same time, (they might be using the same resource) and pause, let f2 or f1 finish, and then resume the infinite loop in x(). How can I do this?

I've looked at join() but it seems to me it will wait forever for f1() and f2() because it creates a new thread every time and won't terminate.

Here's a photo to explain the flow:

在此处输入图像描述

Here's a possible solution, I added the functions dosomething() dosomething2() dosomething3() into the code to have a working example. I've also changed the timer on the threads to 6 and 10 seconds each instead of 60 and 100 so we don't have to wait that long to see their functionality.

dosomething()

  • prints 'dosomething is running' every second if no other function is running

dosomething2()

  • sets dosomething2.status = 'run'

  • prints 'dosomething2 is running 1st second'

  • waits one second

  • prints 'dosomething2 is running 2nd second'

  • sets dosomething2.status = 'sleep'

dosomething3()

  • sets dosomething3.status = 'run'

  • prints 'dosomething3 is running 1st second'

  • waits one second

  • prints 'dosomething3 is running 2nd second'

  • waits one second

  • prints 'dosomething3 is running 3rd second'

  • sets dosomething3.status = 'sleep'

The first and last lines in dosomething2() and dosomething3() will be triggers to let our x() function know to run only if both functions are in the state of 'sleep' .

You could use global variables instead of dosomething2.status and dosomething3.status but some people recommend not using them.

Code

import time
import threading


def dosomething():
    print('dosomething is running')
    time.sleep(1)

def dosomething2():
    dosomething2.status = 'run'
    print('\tdosomething2 is running 1st second')
    time.sleep(1)
    print('\tdosomething2 is running 2nd second')
    dosomething2.status = 'sleep'

def dosomething3():
    dosomething3.status = 'run'
    print('\tdosomething3 is running 1st second')
    time.sleep(1)
    print('\tdosomething3 is running 2nd second')
    time.sleep(1)
    print('\tdosomething3 is running 3rd second')
    dosomething3.status = 'sleep'

dosomething2.status = ''
dosomething3.status = ''

def x():
    while True:
        if dosomething2.status == 'sleep' and dosomething3.status == 'sleep':
            dosomething()

def f1():
    dosomething2()
    threading.Timer(6,f1).start()

def f2():
    dosomething3()
    threading.Timer(10,f2).start()


t1 = threading.Thread(target=x)
t2 = threading.Thread(target=f1)
t3 = threading.Thread(target=f2)

t1.start()
t2.start()
t3.start()

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