df86
df86

Reputation: 35

Does lock need to be declared as global?

Python 3.x

import threading

lock = threading.Lock()
counter = 0

def update_counter():
    global counter

    lock.acquire()
    counter += 1
    lock.release()

# starts threads, target update_counter

Does lock have to be global as well? If not, how does it not cause an error as local lock isn't defined?

Thank you

Upvotes: 3

Views: 1689

Answers (2)

Curtis Lusmore
Curtis Lusmore

Reputation: 1872

To answer the question directly, the reason that counter needs to be declared global and lock doesn't is because you are reassigning to counter (with counter += 1) whereas you are only calling methods on lock. For references to a variable, if no local variable exists Python will look in enclosing scopes until it finds a match. In this case, it finds it in the global scope. For assignments to variables, Python will assume the variable is local unless explicitly declared otherwise (with global or nonlocal).

Upvotes: 2

tdelaney
tdelaney

Reputation: 77367

Locks protect some resource and are generally scoped the same as the resource. In your case you are protecting a global counter so the lock must be global also. All threads that access the resource must use the same lock so it wouldn't do any good to create a private lock in the function itself - no other thread would see it.

Some applications use a single lock to protect all shared resources (course-grained locking). But you could also keep locks with the data (fine-grained locking). An example of fine grained locking is:

class MyCounter:

    def __init__(self):
        self.lock = threading.Lock()
        self.value = 0

    def increment(self):
        with self.lock:
            self.value += 1

Now, each instance of MyCounter has a lock and runs independently.

Upvotes: 1

Related Questions