Search code examples
pythonconcurrencymultiprocessingsubprocesspopen

Run external application on multiple processors


Currently I have a program that uses subprocess.Popen to open an executable file and pass an argument - equivalent to running ./path/to/file args on Linux.

This works very well but I have to execute this file over 1000 times and currently it is done one at a time, on a single processor. I want to be able to execute this file in sets of 8 for example, as I have an 8-core PC.

I have tried the following:

bolsig = ("/home/rdoyle/TEST_PROC/BOLSIG/bolsigminus")

infile_list = glob.glob(str(cwd)+"/BOLSIG Run Files/run*")

cmds_list = [[bolsig, infile] for infile in infile_list]
procs_list = [Popen(cmd) for cmd in cmds_list]           

for proc in procs_list:        
    proc.wait() 

But this tries to execute all 1000 commands at the same time.

Anyone have any suggestions?


Solution

  • I like concurrent.futures for simple cases like this, it's so simple and yet so effective.

    import os
    import glob
    from concurrent import futures
    from subprocess import Popen
    
    optim = ("/usr/bin/jpegoptim")
    img_path = os.path.join(os.path.abspath(os.path.curdir), 'images')
    
    file_list = glob.glob(img_path+'/*jpg')
    
    def compress(fname):
        Popen([optim, fname, '-d', 'out/', '-f'])
    
    ex = futures.ThreadPoolExecutor(max_workers=8)
    ex.map(compress, file_list)
    

    A great intro at Doug Hellman's PyMOTW. https://pymotw.com/3/concurrent.futures/