-1

I have a python program as follows

def send_request(data):
    global lock
    lock.acquire()
    print(data)
    lock.release()

if __name__ == '__main__':
    data_list = ['data1', 'data2', 'data3']
    lock = multiprocessing.Lock()
    pool = multiprocessing.Pool(3)

    pool.map(send_request, data_list)
    pool.close()
    pool.join()

Why did this error occur? NameError: name 'lock' is not defined.

updated

In the answer below, @Jean-François Fabre said that the reason is because “When running your subprocesses, python is "forking" and doesn't see the lock declaration, because it doesn't execute the __main__ part in subprocesses.” But in the following example, the subprocess should not see the lock definition too, but why is the program working fine?

import multiprocessing

def send_request(data):
   lock.acquire()
   print(data,' ',os.getpid())
   lock.release()

def init(l):
   global lock
   lock = l

if __name__ == '__main__':
   data_list = ['data1', 'data2', 'data3']
   lock = multiprocessing.Lock()
   pool = multiprocessing.Pool(8, initializer=init, initargs=(lock,))
   pool.map(send_request, data_list)
   pool.close()
   pool.join()
wjandrea
  • 23,210
  • 7
  • 49
  • 68
inaMinute
  • 463
  • 1
  • 7
  • 14

1 Answers1

1

In the context of multiprocessing, you have to do more than that.

When running your subprocesses, python is "forking" and doesn't see the lock declaration, because it doesn't execute the __main__ part in subprocesses.

Plus, on Windows (which doesn't have fork, the forking is emulated, leading to different behaviour compared to Unix-like platforms: in a nutshell, fork is able to resume the new process where the old process started, but on Windows, Python has to run a new process from the beginning and take control afterwards, this leads to side effects)

You have to create your lock as a global variable outside the __main__ test (and you can drop global keyword, it will work without it)

import multiprocessing

lock = multiprocessing.Lock()

def send_request(data):
    lock.acquire()
    print(data)
    lock.release()

with those modifications your program prints

data1
data2
data3

as expected.

Jean-François Fabre
  • 131,796
  • 23
  • 122
  • 195