Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><code>if __name__ == '__main__'</code>is mandatory(at least in windows), if one wants to use multiprocessing. </p> <p>In windows it works like this: For every worker thread that you want to generate, windows will automatically start the main process, and all needed files again. However, only the first process that has been started is called <strong>main</strong>. This is why blocking execution of mt_factorizer with <code>if __name__ == '__main__'</code> prevents multiprocessing from creating an infinite loop.</p> <p>So essentially windows needs to read the file that contains the worker, and all functions the worker calls - for each worker. By blocking mt_factorizer we make sure that no additional workers will be created, while windows can still execute the workers. This is the reason why multiprocessing examples that have all code in one file block the creation of workers (like mt_factorizer does in this case) directly (but not the worker function), so windows can still execute the worker function. If all code is in one file, and the whole file is being protected, no worker could be created.</p> <p>If the multiprocessing code is located in another class and being called, <code>if __name__ == '__main__'</code> needs to be implemented directly above the call: mpteststart.py</p> <pre><code>import random import mptest as smt l = [] for i in range(4): l.append(random.randint(1,8)) print "Random numbers generated" if __name__ == '__main__': print smt.mp_factorizer(l, 4) </code></pre> <p>mptest.py</p> <pre><code>import multiprocessing import math print "Reading mptest.py file" def mp_factorizer(nums, nprocs): out_q = multiprocessing.Queue() chunksize = int(math.ceil(len(nums) / float(nprocs))) procs = [] for i in range(nprocs): p = multiprocessing.Process( target=worker, args=(nums[chunksize * i:chunksize * (i + 1)], out_q)) procs.append(p) p.start() # Collect all results into a single result dict. We know how many dicts # with results to expect. resultlist = [] for i in range(nprocs): temp=out_q.get() index =0 #print temp for i in temp: resultlist.append(temp[index][0][0:]) index +=1 # Wait for all worker processes to finish for p in procs: p.join() resultlist2 = [x for x in resultlist if x != []] return resultlist2 def worker(nums, out_q): """ The worker function, invoked in a process. 'nums' is a list of numbers to factor. The results are placed in a dictionary that's pushed to a queue. """ outlist = [] for n in nums: newnumber= n*2 newnumberasstring = str(newnumber) if newnumber: outlist.append(newnumberasstring) out_q.put(outlist) </code></pre> <p>In above code, <code>if __name__ == '__main__'</code> has been removed since it is already in the calling file. </p> <p>However, the result is somewhat unexpected: </p> <pre><code>Reading mptest.py file random numbers generated Reading mptest.py file random numbers generated worker started Reading mptest.py file random numbers generated worker started Reading mptest.py file random numbers generated worker started Reading mptest.py file random numbers generated worker started ['1', '1', '4', '1'] </code></pre> <p>Multiprocessing is being blocked from endless execution, but the rest of the code still is being executed several times(Random number generation in this case). This will not only result in a performance decrease, but also may lead to other nasty bugs. The solution is to protect the whole main process from being repeatedly executed by windows, if multiprocessing is being used somewhere down the line: mptest.py</p> <pre><code>import random import mptest as smt if __name__ == '__main__': l = [] for i in range(4): l.append(random.randint(1,8)) print "random numbers generated" print smt.mp_factorizer(l, 4) </code></pre> <p>Now all we get back is the desired result, the random numbers are only generated once:</p> <pre><code>Reading mptest.py file random numbers generated Reading mptest.py file worker started Reading mptest.py file worker started Reading mptest.py file worker started Reading mptest.py file worker started ['1', '6', '2', '1'] </code></pre> <p>Note that in this example, mpteststart.py is the main process. If it is not, <code>if __name__ == '__main__'</code> has to be moved up the calling chain until it is in the main process. Once the main process is being protected that way, there will be no unwanted repeated code execution anymore.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload