2

I have a problem where I need to wait in a for loop for a while till the value of a Boolean variable is changed. I intentionally want to wait in the loop. Sample code:

check = True  

def change_check_value():
    global check
    ###
    after a while check changes to true
    ###

change_check_vale()  #running on a different thread

for i in range(0,10):
    print(i)
    check = False
    ## wait till check becomes true and continue the for loop

I want to wait in the for loop till the check becomes true again. I tried with while loop but I was not able to achieve the functionality. time.sleep() cannot be used because I am not sure of how much time to wait.

halfer
  • 19,824
  • 17
  • 99
  • 186
chink
  • 1,505
  • 3
  • 28
  • 70
  • 2
    You can use `time.sleep`, you just might end up waiting longer than you really need to. The other option is a [condition variable](https://docs.python.org/3/library/threading.html#condition-objects). – Paul Rooney Dec 18 '19 at 05:30

3 Answers3

2

Try using the method as mentioned in this post : Is there an easy way in Python to wait until certain condition is true?

import time

check = True

def wait_until():
  while true:
    if check == True: return


def change_check_value():
    global check
    ###
    after a while check changes to true
    ###

change_check_vale()  #running on a different thread

for i in range(0,10):
    print(i)
    check = False
    ## wait till check becomes true and continue the for loop
    wait_until()

Hope it helps.

aru_sha4
  • 368
  • 2
  • 11
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/24885230) – Inder Dec 18 '19 at 06:28
  • 1
    Ok. Thanks for the review. – aru_sha4 Dec 18 '19 at 06:33
2

You can use the Event object, it may be found under threading and under the asyncio packages.

The event object have a wait() method and while calling it the code will not continue until the Event will set to true. Once the event will be set to True the code will immediately continue.

asyncio example (source):

async def waiter(event):
    print('waiting for it ...')
    await event.wait()
    print('... got it!')

async def main():
    # Create an Event object.
    event = asyncio.Event()

    # Spawn a Task to wait until 'event' is set.
    waiter_task = asyncio.create_task(waiter(event))

    # Sleep for 1 second and set the event.
    await asyncio.sleep(1)
    event.set()

    # Wait until the waiter task is finished.
    await waiter_task

asyncio.run(main())

Threading example (source):

import threading
import time
import logging

logging.basicConfig(level=logging.DEBUG,
                    format='(%(threadName)-9s) %(message)s',)

def wait_for_event(e):
    logging.debug('wait_for_event starting')
    event_is_set = e.wait()
    logging.debug('event set: %s', event_is_set)

def wait_for_event_timeout(e, t):
    while not e.isSet():
        logging.debug('wait_for_event_timeout starting')
        event_is_set = e.wait(t)
        logging.debug('event set: %s', event_is_set)
        if event_is_set:
            logging.debug('processing event')
        else:
            logging.debug('doing other things')

if __name__ == '__main__':
    e = threading.Event()
    t1 = threading.Thread(name='blocking', 
                      target=wait_for_event,
                      args=(e,))
    t1.start()

    t2 = threading.Thread(name='non-blocking', 
                      target=wait_for_event_timeout, 
                      args=(e, 2))
    t2.start()

    logging.debug('Waiting before calling Event.set()')
    time.sleep(3)
    e.set()
    logging.debug('Event is set')
Amiram
  • 1,227
  • 6
  • 14
0

This can be done in a very straightforward way:

from threading import Event, Thread

event = Event()


def wait_for_it(e):
    print('Waiting for something to happen.')
    e.wait()
    print('No longer waiting.')
    e.clear()
    print('It can happen again.')


def make_it_happen(e):
    print('Making it happen.')
    e.set()
    print('It happened.')


# create the threads
threads = [Thread(target=wait_for_it, args=(event,)), Thread(target=make_it_happen, args=(event,))]

# start them
for thread in threads:
    thread.start()

# make the main thread wait for the others to complete
for thread in threads:
    thread.join()
Grismar
  • 27,561
  • 4
  • 31
  • 54