ealeon
ealeon

Reputation: 12462

python threading: event vs global variable

using global variable

event = False
def wait_for_event_timeout(e, t):
    time.sleep(5)
    global event
    event = True


if __name__ == '__main__':
    t2 = threading.Thread(name='non-blocking',
                      target=wait_for_event_timeout,
                      args=(e, 1))
    t2.start()

    while True:
        time.sleep(1)
        if event:
            logging.debug('got event')
            break
        else:
            logging.debug('doing other things')

using threading.event

def wait_for_event_timeout(e, t):
    time.sleep(5)
    e.set()

if __name__ == '__main__':
    e = threading.Event()

    t2 = threading.Thread(name='non-blocking',
                      target=wait_for_event_timeout,
                      args=(e, 1))
    t2.start()
    while True:
        event_is_set = e.wait(1)
        if event_is_set:
            logging.debug('got event')
            break
        else:
            logging.debug('doing other things')

Looks like i can do the same by using global variable

Whats the use case for event?
When do i want to use it over using global variable?

Upvotes: 2

Views: 2341

Answers (2)

dano
dano

Reputation: 94921

In addition to the important difference Ami Tavory pointed out, Event is nicer than a global variable if you want to wait without "doing other things" while you wait, since you don't need to use a while loop:

def wait_for_event_timeout(e, t):
    time.sleep(5)
    e.set()

if __name__ == '__main__':
    e = threading.Event()

    t2 = threading.Thread(name='non-blocking',
                      target=wait_for_event_timeout,
                      args=(e, 1))
    t2.start()
    e.wait()
    logging.debug('got event')

vs

event = False
def wait_for_event_timeout(e, t):
    time.sleep(5)
    global event
    event = True

if __name__ == '__main__':
    t2 = threading.Thread(name='non-blocking',
                      target=wait_for_event_timeout,
                      args=(e, 1))
    t2.start()

    while True:
        time.sleep(1)
        if event:
            logging.debug('got event')
            break

Not having to use a busy loop like this means you can leave the GIL released while you wait on the event, which will improve the performance of other threads in your application. Plus the code is more concise and readable.

Upvotes: 2

Ami Tavory
Ami Tavory

Reputation: 76336

There is a fundamental difference between the two. When you write

event_is_set = e.wait(1)

then you are stating to wait for a maximal time If, during the wait, the other thread has triggered a change, it will be noted (nearly) immediately. Conversely,

time.sleep(1)

is an unconditional time. If, during the wait, the other thread has triggered a change, it will be not be noted until the sleep has ended.

The event, therefore, is inherently more responsive than the latter.

Upvotes: 6

Related Questions