def run(self, func, tasks, func2=None):
<EOL>progress = <NUM_LIT:1><EOL>total = len(tasks)<EOL>if len(tasks) == <NUM_LIT:0>:<EOL><INDENT>return<EOL><DEDENT>if func2 is not None:<EOL><INDENT>total = total * <NUM_LIT:2><EOL><DEDENT>finished = []<EOL>level1 = []<EOL>results = []<EOL>try:<EOL><INDENT>prefix = "<STR_LIT>" % (progress, total)<EOL>bot.show_progress(<NUM_LIT:0>, total, length=<NUM_LIT>, prefix=prefix)<EOL>pool = multiprocessing.Pool(self.workers, init_worker)<EOL>self.start()<EOL>for task in tasks:<EOL><INDENT>result = pool.apply_async(multi_wrapper,<EOL>multi_package(func, [task]))<EOL>results.append(result)<EOL>level1.append(result._job)<EOL><DEDENT>while len(results) > <NUM_LIT:0>:<EOL><INDENT>result = results.pop()<EOL>result.wait()<EOL>bot.show_progress(progress, total, length=<NUM_LIT>, prefix=prefix)<EOL>progress += <NUM_LIT:1><EOL>prefix = "<STR_LIT>" % (progress, total)<EOL>if func2 is not None and result._job in level1:<EOL><INDENT>result = pool.apply_async(multi_wrapper,<EOL>multi_package(func2,<EOL>[(result.get(),)]))<EOL>results.append(result)<EOL><DEDENT>else:<EOL><INDENT>finished.append(result.get())<EOL><DEDENT><DEDENT>self.end()<EOL>pool.close()<EOL>pool.join()<EOL><DEDENT>except (KeyboardInterrupt, SystemExit):<EOL><INDENT>bot.error("<STR_LIT>")<EOL>pool.terminate()<EOL>sys.exit(<NUM_LIT:1>)<EOL><DEDENT>except Exception as e:<EOL><INDENT>bot.error(e)<EOL><DEDENT>return finished<EOL>
run will send a list of tasks,
        a tuple with arguments, through a function.
        the arguments should be ordered correctly.
        :param func: the function to run with multiprocessing.pool
        :param tasks: a list of tasks, each a tuple
                      of arguments to process
        :param func2: filter function to run result
                      from func through (optional)