chink
chink

Reputation: 1643

How to get stuck in a for loop?

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.

Upvotes: 2

Views: 216

Answers (3)

aru_sha4
aru_sha4

Reputation: 378

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.

Upvotes: 2

Grismar
Grismar

Reputation: 31319

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()

Upvotes: 0

Amiram
Amiram

Reputation: 1295

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')

Upvotes: 2

Related Questions