【问题标题】:How to know how many threads / workers from a pool in multiprocessing (Python module) has been completed?如何知道多处理(Python 模块)中的池中有多少线程/工作者已完成?
【发布时间】:2019-02-25 12:34:56
【问题描述】:

我正在使用 imapala shell 通过包含表名的文本文件计算一些统计信息。

我正在使用 Python 多处理模块来汇集进程。
事情是事情任务非常耗时,所以我需要跟踪完成了多少文件才能查看工作进度。
所以让我给你一些关于我正在使用的功能的想法。

job_executor 是获取表列表并执行任务的函数。

main() 是函数,它获取文件位置,没有执行程序(pool_workers),将包含表的文件转换为表列表并执行多处理操作

我想查看 job_executor 处理了多少文件等进度,但我找不到解决方案。使用计数器也不起作用。

def job_executor(text):

    impala_cmd = "impala-shell -i %s -q  'compute stats %s.%s'" % (impala_node, db_name, text)
    impala_cmd_res = os.system(impala_cmd)  #runs impala Command    

    #checks for execution type(success or fail)
    if impala_cmd_res == 0:
        print ("invalidated the metadata.")
    else:
        print("error while performing the operation.")


def main(args):
    text_file_path = args.text_file_path
    NUM_OF_EXECUTORS = int(args.pool_executors)

    with open(text_file_path, 'r') as text_file_reader:
        text_file_rows = text_file_reader.read().splitlines()  # this will return list of all the tables in the file.
        process_pool = Pool(NUM_OF_EXECUTORS)
        try:
            process_pool.map(job_executor, text_file_rows)
            process_pool.close()
            process_pool.join()
        except Exception:
            process_pool.terminate()
            process_pool.join()


def parse_args():
    """
    function to take scraping arguments from  test_hr.sh file
    """
    parser = argparse.ArgumentParser(description='Main Process file that will start the process and session too.')
    parser.add_argument("text_file_path",
                        help='provide text file path/location to be read. ')  # text file fath
    parser.add_argument("pool_executors",
                        help='please provide pool executors as an initial argument') # pool_executor path

    return parser.parse_args() # returns list/tuple of all arguments.


if __name__ == "__main__":
    mail_message_start()

    main(parse_args())

    mail_message_end()

【问题讨论】:

  • 让我们从一个显而易见的问题开始 - 为什么您使用多处理只是为了运行外部进程?无论如何,外部进程都将作为单独的进程运行,因此您正在做的整个多处理舞蹈是一大浪费。线程对此非常适用,然后您可以共享指向每个子进程的指针以查看它们的进展情况。
  • @zwer 。实际上这些 impala 是在 hadoop 集群上产生的,所以它必须有多个 cpu。所以要利用我们正在使用的东西 this 。问题是该代码已经存在,我无权对其功能方法进行任何更改。因此,如果您能告诉我或帮助我告诉如何跟踪上述代码的进度,那将非常有帮助。谢谢
  • 如果您无法更改代码,您希望如何添加流程跟踪?那么你只能在外部通过监控impala-shell进程并监控它们的资源使用情况来做到这一点。此外,在这种情况下,多处理与使用多个 CPU 无关 - 您可以在单个线程中运行所有 job_executor() 调用,在单个循环中,如果可用,它们仍将在单独的 CPU 上执行(只是不要使用半弃用的os.system(),改用subprocess.Popen() 以确保非阻塞调用)。
  • @zwer 。我被授权添加一些只负责跟踪进度的代码行。我不应该在此文件中添加或删除任何其他代码行。希望你能理解。

标签: python python-3.x multithreading python-2.7 multiprocessing


【解决方案1】:

如果您坚持通过multiprocessing.pool.Pool() 进行不必要的操作,跟踪正在发生的事情的最简单方法是使用非阻塞映射(即multiprocessing.pool.Pool.map_async()):

def main(args):
    text_file_path = args.text_file_path
    NUM_OF_EXECUTORS = int(args.pool_executors)

    with open(text_file_path, 'r') as text_file_reader:
        text_file_rows = text_file_reader.read().splitlines()
        total_processes = len(text_file_rows)  # keep the number of lines for reference
        process_pool = Pool(NUM_OF_EXECUTORS)
        try:
            print('Processing {} lines.'.format(total_processes))
            processing = process_pool.map_async(job_executor, text_file_rows)
            processes_left = total_processes  # number of processing lines left
            while not processing.ready():  # start a loop to wait for all to finish
                if processes_left != processing._number_left:
                    processes_left = processing._number_left
                    print('Processed {} out of {} lines...'.format(
                        total_processes - processes_left, total_processes))
                time.sleep(0.1)  # let it breathe a little, don't forget to `import time`
            print('All done!')
            process_pool.close()
            process_pool.join()
        except Exception:
            process_pool.terminate()
            process_pool.join()

这将每 100 毫秒检查一些进程是否已完成处理,如果自上次检查后发生更改,它将打印出到目前为止已处理的行数。如果您需要更深入地了解您的子流程发生了什么,您可以使用一些共享结构,如multiprocessing.Queue()multiprocessing.Manager() 结构直接从您的流程中报告。

【讨论】:

    猜你喜欢
    • 2015-07-30
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多