I was just having a go with how to use the multiprocessing.Lock()
Working from the examples on:
http://docs.python.org/2/library/multiprocessing.html
This example in fact:
from multiprocessing import Process, Lock
def f(l, i):
l.acquire()
print 'hello world', i
l.release()
if __name__ == '__main__':
lock = Lock()
for num in range(10):
Process(target=f, args=(lock, num)).start()
I had this as my code:
from multiprocessing import Process, Lock
import datetime
import time
import random
def function(lock, i):
now = datetime.datetime.now()
time.sleep(random.randint(0,3))
lock.acquire()
print "%s says hello, World! at time: %s" % (i,now)
lock.release()
lock = Lock()
for i in range(2):
Process(target=function,args=(lock,i)).start()
Running it in a shell, causes the computer to lock up at 100% cpu with dozens of python.exe's running in cmd. While all the time printing the message from either process 0 or one. Looking at the example I realised that I had missed the:
if __name__ == '__main__':
So I added it fearing the cargo code Gods, and lone behold:
from multiprocessing import Process, Lock
import datetime
import time
import random
def function(lock, i):
now = datetime.datetime.now()
time.sleep(random.randint(0,3))
lock.acquire()
print "%s says hello, World! at time: %s" % (i,now)
lock.release()
if __name__ == "__main__":
lock = Lock()
for i in range(2):
Process(target=function,args=(lock,i)).start()
Prints:
1 says hello, World! at time: 2013-05-20 19:40:13.843000
0 says hello, World! at time: 2013-05-20 19:40:13.843000
Edit thought it might be to do with the namespace so I tried:
from multiprocessing import Process, Lock
import datetime
import time
import random
def function(l, i):
now = datetime.datetime.now()
time.sleep(random.randint(0,3))
l.acquire()
print "%s says hello, World! at time: %s" % (i,now), i
l.release()
lock = Lock()
for i in range(2):
Process(target=function,args=(lock,i)).start()
Still the same issue
Colour me confused?! Can anyone give an explanation to this?
Final Edit:
This is how I have finished my little example code now:
from multiprocessing import Process, Lock
import datetime
import time
import random
print "imports done"
def function(l, i):
now = datetime.datetime.now()
time.sleep(random.randint(0,3))
l.acquire()
print "%s says hello, World! at time: %s" % (i,now)
l.release()
def main():
lock = Lock()
for i in range(2):
Process(target=function,args=(lock,i)).start()
if __name__ == "__main__":
main()
Which prints:
imports done
imports done
imports done
1 says hello, World! at time: 2013-05-20 23:26:41.015000
0 says hello, World! at time: 2013-05-20 23:26:41.015000
Your script doesn't take over my Ubuntu computer, but it will take over a Windows computer. Here's the explanation:
multiprocessing requires that the child processes be able to import __main__. What happens on *NIX is that the child processes are created via os.fork which means that they're essentially cloned from the parent process with __main__ already imported. Importing it again does no harm.
On Windows, there is no os.fork, so the children actually need to import __main__ again. But, when they import __main__, all of the code in that script gets executed which leads to the children spawing more children. When you use the
if __name__ == "__main__":
clause, you prevent the infinite loop of children spawning children.
This is actually documented to an extent in the multiprocessing specification.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With