0

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:

enter image description here

1 Answer 1

0

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()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.