Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: multithreading setting the variable once

Does the following code thread-safe?
Will only one/first thread set the variable, set_this_var_only_once?

set_this_var_only_once = None

def worker():
    global set_this_var_only_once
    if set_this_var_only_once is None:
        set_this_var_only_once = "not None"

for i in range(10):
    t = threading.Thread( target=worker )
    t.daemon=True
    t.start()
like image 839
ealeon Avatar asked Sep 20 '26 03:09

ealeon


2 Answers

Absolutely not.

It is quite possible that two threads execute this line before executing the next one:

    if set_this_var_only_once is None:

After that, both threads will execute the next line:

        set_this_var_only_once = "not None"

You can use locks to prevent that:

lock = threading.Lock()

def worker():
    lock.acquire()
    if set_this_var_only_once is None:
        set_this_var_only_once = "not None"
    lock.release()

Only one thread will be able to acquire the lock. If another thread tries to acquire it while it is locked, the call to lock.acquire() will block and wait until the lock is released by the first thread. Then the lock will be acquired by the other thread.

That way it is ensured that the code between lock.acquire() and lock.release() is executed in one thread at a time.

EDIT

As Gerhard pointed in the other answer, you can use the context management protocol with locks:

with lock:
    if set_this_var_only_once is None:
        set_this_var_only_once = "not None"

That will also make sure the lock is correctly released in case of an exception within the locked block.

like image 158
zvone Avatar answered Sep 22 '26 17:09

zvone


You need to lock the variable like this:

from threading import Lock

lock = Lock()
set_this_var_only_once = None

def worker():
    with lock:
        if set_this_var_only_once is None:
            set_this_var_only_once = "not None
like image 20
Gerhard Hagerer Avatar answered Sep 22 '26 16:09

Gerhard Hagerer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!