如何区分Multiprocessing.Pool中的进程?

陈胜坤

我正在使用pythonmultiprocessing派生一些子进程来运行我的工作。有两个要求:

  1. 如果需要,我需要知道子进程的pid,以将其杀死。
  2. 工作完成后,我需要回调来做一些事情。因为这些东西在父进程中使用了锁,所以不能在子进程中完成。

但我得到:

  1. 生成的进程by multiprocessing.Process()具有属性“ pid”以获取其pid。但是我不能添加异步回调,当然我也不能同步等待。
  2. 提供的进程池multiprocessing.Pool()提供回调接口。但是我无法确定池中哪个进程与我的工作匹配,因为我可能需要根据特定的工作来终止该进程。

任务很便宜,这里显示代码:

import random, time
import multiprocessing
import os

class Job(object):
    def __init__(self, jobid, jobname, command):
        self.jobid, self.jobname, self.command = jobid, jobname, command

    def __str__(self):
        return "Job <{0:05d}>".format(self.jobid)

    def __repr__(self):
        return self.__str__()

def _run_job(job):
    time.sleep(1)
    print "{} done".format(job)
    return job, random.choice([True, False]) # the second argument indicates whether job has finished successfully

class Test(object):
    def __init__(self):
        self._loc = multiprocessing.Lock()
        self._process_pool = multiprocessing.Pool()

    def submit_job(self, job):
        with self._loc:
            self._process_pool.apply_async(_run_job, (job,), callback=self.job_done)
            print "submitting {} successfully".format(job)

    def job_done(self, result):
        with self._loc:
            # stuffs after job has finished is related to some cleanning work, so it needs the lock of the parent process
            job, success = result
            if success:
                print "{} success".format(job)
            else:
                print "{} failure".format(job)


j1 = Job(1, "test1", "command1")
j2 = Job(2, "test2", "command2")
t = Test()
t.submit_job(j1)
t.submit_job(j2)
time.sleep(3.1) # wait for all jobs finishing

但是现在我无法获得与每个工作相对应的pid。例如,我需要终止作业<1>,但是我找不到进程池中与该作业<1>相关的进程,因此我可能不想随时终止该作业。

如果我使用multiprocessing.Process其他方法,则可以记录每个进程的pid及其对应的jobid。但是我现在不能添加回调方法。

那么,有没有一种方法既可以获取子进程的pid,又可以添加回调方法?

陈胜坤

最后,我找到了一个解决方案:multiprocessing.Event改为使用

由于multiprocessing.Pool无法告诉我分配了哪个进程,因此无法记录它,因此我可以随时根据作业ID杀死它。

幸运的是,multiprocessing提供了Eventobject作为回调方法的替代方法。回顾回调方法的作用:它提供对子进程的异步响应。子进程完成后,父进程可以检测到它并调用回调方法。因此,核心问题是父进程如何检测子进程是否已完成。这是Event目的。

因此解决方案很简单:将Event对象传递给子进程。子进程完成后,它将设置Event对象。在父进程中,它启动守护程序线程以监视是否设置了事件。如果是这样,它可以调用执行这些回调操作的方法。此外,由于我使用multiprocessing.Process而不是创建了进程multiprocessing.Pool,因此我可以轻松获取其PID,从而可以将其杀死。

解决方案代码:

import time
import multiprocessing
import threading

class Job(object):
    def __init__(self, jobid, jobname, command):
        self.jobid, self.jobname, self.command = jobid, jobname, command
        self.lifetime = 0

    def __str__(self):
        return "Job <{0:05d}>".format(self.jobid)

    def __repr__(self):
        return self.__str__()

def _run_job(job, done_event):
    time.sleep(1)
    print "{} done".format(job)
    done_event.set()

class Test(object):
    def __init__(self):
        self._loc = multiprocessing.Lock()
        self._process_pool = {}
        t = threading.Thread(target=self.scan_jobs)
        t.daemon = True
        t.start()

    def scan_jobs(self):
        while True:
            with self._loc:
                done_jobid = []
                for jobid in self._process_pool:
                    process, event = self._process_pool[jobid]
                    if event.is_set():
                        print "Job<{}> is done in process <{}>".format(jobid, process.pid)
                        done_jobid.append(jobid)
                map(self._process_pool.pop, done_jobid)
            time.sleep(1)


    def submit_job(self, job):
        with self._loc:
            done_event = multiprocessing.Event()
            new_process = multiprocessing.Process(target=_run_host_job, args=(job, done_event))
            new_process.daemon = True
            self._process_pool[job.jobid] = (new_process, done_event)
            new_process.start()
            print "submitting {} successfully".format(job)


j1 = Job(1, "test1", "command1")
j2 = Job(2, "test2", "command2")
t = Test()
t.submit_job(j1)
t.submit_job(j2)
time.sleep(5) # wait for job to finish

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在multiprocessing.pool中命名进程?

来自分类Dev

如何在多进程中杀死所有Pool工人?

来自分类Dev

如何区分同名进程

来自分类Dev

在长时间运行的任务中杀死QThread和multiprocessing.pool进程

来自分类Dev

python,multiprocessing和dmtcp:在Pool中检查一个进程?

来自分类Dev

如何在超时后中止multiprocessing.Pool中的任务?

来自分类Dev

检索使用multiprocessing.Pool.map启动的进程的退出代码

来自分类Dev

如果创建multiprocessing.Pool,则Python子进程wait()失败

来自分类Dev

检索使用multiprocessing.Pool.map启动的进程的退出代码

来自分类Dev

如何通过使用Java在Powershell中获取进程名称和ID来区分系统进程和正常进程

来自分类Dev

如何区分R中的功能

来自分类Dev

如何在python中使用multiprocessing.Pool.map实现对象中的功能?

来自分类Dev

如何在python中使用multiprocessing.Pool.map实现对象中的功能?

来自分类Dev

利用“写时复制”功能将数据复制到Multiprocessing.Pool()工作进程

来自分类Dev

提前退出multiprocessing.Pool.map(在子进程中进行提升不起作用)

来自分类Dev

列表长于进程数时的Python multiprocessing.Pool.map行为

来自分类Dev

python multiprocessing.pool.map,将参数传递给生成的进程

来自分类Dev

如何区分使用相同名称的不同进程?

来自分类Dev

如何区分具有相同名称的进程

来自分类Dev

如何区分使用相同名称的不同进程?

来自分类Dev

在git中如何区分Microsoft Word文档?

来自分类Dev

如何区分表单中的按钮单击?

来自分类Dev

如何区分CSS中的无序列表?

来自分类Dev

如何使用CustomArrayAdapter区分ListFragment中的视图?

来自分类Dev

如何区分图形或数组中的多个形状?

来自分类Dev

如何区分日期列表中的日期?的PHP

来自分类Dev

如何区分networkx中的等效图

来自分类Dev

如何区分打字稿中的日期?

来自分类Dev

如何从R中的.png图像区分材质?

Related 相关文章

  1. 1

    如何在multiprocessing.pool中命名进程?

  2. 2

    如何在多进程中杀死所有Pool工人?

  3. 3

    如何区分同名进程

  4. 4

    在长时间运行的任务中杀死QThread和multiprocessing.pool进程

  5. 5

    python,multiprocessing和dmtcp:在Pool中检查一个进程?

  6. 6

    如何在超时后中止multiprocessing.Pool中的任务?

  7. 7

    检索使用multiprocessing.Pool.map启动的进程的退出代码

  8. 8

    如果创建multiprocessing.Pool,则Python子进程wait()失败

  9. 9

    检索使用multiprocessing.Pool.map启动的进程的退出代码

  10. 10

    如何通过使用Java在Powershell中获取进程名称和ID来区分系统进程和正常进程

  11. 11

    如何区分R中的功能

  12. 12

    如何在python中使用multiprocessing.Pool.map实现对象中的功能?

  13. 13

    如何在python中使用multiprocessing.Pool.map实现对象中的功能?

  14. 14

    利用“写时复制”功能将数据复制到Multiprocessing.Pool()工作进程

  15. 15

    提前退出multiprocessing.Pool.map(在子进程中进行提升不起作用)

  16. 16

    列表长于进程数时的Python multiprocessing.Pool.map行为

  17. 17

    python multiprocessing.pool.map,将参数传递给生成的进程

  18. 18

    如何区分使用相同名称的不同进程?

  19. 19

    如何区分具有相同名称的进程

  20. 20

    如何区分使用相同名称的不同进程?

  21. 21

    在git中如何区分Microsoft Word文档?

  22. 22

    如何区分表单中的按钮单击?

  23. 23

    如何区分CSS中的无序列表?

  24. 24

    如何使用CustomArrayAdapter区分ListFragment中的视图?

  25. 25

    如何区分图形或数组中的多个形状?

  26. 26

    如何区分日期列表中的日期?的PHP

  27. 27

    如何区分networkx中的等效图

  28. 28

    如何区分打字稿中的日期?

  29. 29

    如何从R中的.png图像区分材质?

热门标签

归档