Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiprocessing - Process owns my computer

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 
like image 999
Noelkd Avatar asked Jul 29 '26 23:07

Noelkd


1 Answers

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.

like image 120
mgilson Avatar answered Aug 01 '26 12:08

mgilson



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!