title: Python Multiprocessing - Use Array(), Lock() and Pool()
body: <p>I've been struggling with this program for some time.</p>
  
  <p>I wrote this program to learn how to run the same program in different CPU's at the same time and to reduce processing time.</p>
  
  <p>By itself, the program is not complex, just detect if there are some screenshots in different directories, but as I said before my final goal is not to detect those files, but to learn multiprocessing.</p>
  
  <p>To be easier to test, instead of reading files or reading user inputs, I just set those variables so you won't have to be typing those things. I'll be faster to test this way.</p>
  
  <p>Here's the code:</p>
  
  <pre><code>from multiprocessing import Array, Lock, Pool
  
  def DetectSCREENSHOT(file, counter, total): 
  
      # To check if this function is ever accessed
      print 'Entered in DetectSCREENSHOT function'
  
      if file.startswith('Screenshot') == False:
  
          print ' (%s %%) ERROR: the image is not a screenshot ' %(round((float(counter)/total)*100, 1))
          return 0
  
      else:       
  
          print ' (%s %%) SUCCESS: the image is a screenshot' %(round((float(counter)/total)*100, 1))
          return 1
  
  def DetectPNG(file_list, counter_success_errors, lock):
  
      # To check if this function is ever accessed
      print 'Entered in DetectPNG function'
  
      for i in range(len(file_list)):
  
          file = file_list[i]
  
          # If the file is an .png image:
  
          if file.endswith('.png'):
  
              lock.acquire()
              counter_success_errors[0] = counter_success_errors[0] + 1
              lock.release()
  
              if DetectSCREENSHOT(file, counter_success_errors[0], len(file_list)) == 1:
  
                  lock.acquire()
                  counter_success_errors[1] = counter_success_errors[1] + 1
                  lock.release()
  
              else:
  
                  lock.acquire()
                  counter_success_errors[2] = counter_success_errors[2] + 1
                  lock.release()
  
  def Main():
  
      # file_list = # List of lists of files in different directories
      file_list = [['A.png', 'B.png', 'C.txt', 'Screenshot_1.png'], ['D.txt', 'Screenshot_2.png', 'F.png', 'Screenshot_3.png']]
  
      # Array where the first cell is a counter, the second one, the number of successes and the third one, the number of errors.
      counter_success_errors = Array('i', 3)
      lock = Lock()
  
      counter_success_errors[0] = 0
      counter_success_errors[1] = 0
      counter_success_errors[2] = 0
  
      # Number of CPUS's to be used (will set the number of different processes to be run)
      # CPUs = raw_input('Number of CPUs &gt;&gt; ')
      CPUs = 2
      pool = Pool(processes=CPUs)
  
      for i in range(CPUs):
          pool.apply_async(DetectPNG, [file_list[i], counter_success_errors, lock])
  
      pool.close()
      pool.join()
  
      success = int(counter_success_errors[1])
      errors = int(counter_success_errors[2])
  
      print(' %s %s %s successfully. %s %s.' %('Detected', success, 'screenshot' if success == 1 else 'screenshots', errors, 'error' if errors == 1 else 'errors'))
  
  #################################################
  
  if __name__ == "__main__":
  Main()
  </code></pre>
  
  <p>When I execute it, I don't get any errors, but it looks like it doesn't even access to both DetectPNG and DetectSCREENSHOT functions.</p>
  
  <p>What's broken in the code?</p>
  
  <p>Output: <code>Detected 0 screenshots successfully. 0 errors.</code></p>