Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Multithreading - Does Lock have to be global?

I am beginner of multithreading in python.
I want to use a Lock in threads. Does it have to be declared global in the thread? My code looks like this:

i = 0
lock = threading.RLock()
def do_work():
  global i
  # global lock ?????????????
  while i < len(my_list):
    lock.acquire()
    my_i = i
    i += 1
    lock.release()
    my_list[my_i].some_works()

workers = [threading.Thread(target=do_work) for _ in range(8)]
for worker in workers:
  worker.start()
like image 329
zardav Avatar asked Feb 11 '16 13:02

zardav


People also ask

Does Python use real threads if it uses a global interpreter lock?

The Python Global Interpreter Lock or GIL, in simple words, is a mutex (or a lock) that allows only one thread to hold the control of the Python interpreter. This means that only one thread can be in a state of execution at any point in time.

Why do we need to lock writing to a global variable when threading a program?

A lock can be used to protect one or multiple shared variables and they may be variables of any type. The shared variables will be protected from race conditions as long as all access and changes to the variables are protected by the lock.

Why does Python have a global interpreter lock?

The Python GIL, or Global Interpreter Lock, is a mechanism in CPython (the most common implementation of Python) that serves to serialize operations involving the Python bytecode interpreter, and provides useful safety guarantees for internal object and interpreter state.


1 Answers

No, it does not have to be global. You can create it in a function and then pass it to your threads as an argument like so:

i = 0

def do_work(lock):
    global i

    while i < len(my_list):
        with lock: # cleaner way to .acquire() and .release()
            my_i = i
            i += 1
         my_list[my_i].some_works()

def main():
    lock = threading.RLock()

    workers = [threading.Thread(target=do_work, args=lock,) for _ in range(8)]
    for worker in workers:
        worker.start()

main()
like image 67
Josh Correia Avatar answered Oct 14 '22 22:10

Josh Correia