处理python多处理进程的kill事件

时间:2015-08-16 21:32:15

标签: python multiprocessing kill-process

对于应该在Linux和Windows上运行的程序(python 2.7),我试图使用multiprocessing.Process更新给定对象的值(当主程序运行时,我' m通过单独的进程调用更新类。)

有时我的对象更新需要很长时间,所以我希望能够终止我的更新过程,并继续使用主程序。 "太长了"这里没有严格定义,而是用户的主观感受。 对于单个队列(如http://pymotw.com/2/multiprocessing/communication.html中的MyFancyClass示例),我可以终止更新过程,主程序继续进行。 但是,当我创建第二个队列来检索更新的对象时,结束更新过程不允许我继续在主程序中。

到目前为止我所拥有的是:

import multiprocessing
import time, os

class NewParallelProcess(multiprocessing.Process):

    def __init__(self, taskQueue, resultQueue, processName):
        multiprocessing.Process.__init__(self)
        self.taskQueue      = taskQueue
        self.resultQueue    = resultQueue
        self.processName    = processName


    def run(self):
        print "pid %s of process that could be killed" % os.getpid()
        while True:
            next_task = self.taskQueue.get()
            if next_task is None:
                # poison pill for terminate
                print "%s: exiting" % self.processName
                self.taskQueue.task_done()
                break
            print "%s: %s" % (self.processName, next_task)
            answer = next_task()
            self.taskQueue.task_done()
            self.resultQueue.put(answer)

        return



class OldObject(object):
    def __init__(self):
        self.accurate       = "OldValue"
        self.otherValue     = "SomeOtherValue"



class UpdateObject(dict):
    def __init__(self, objectToUpdate):
        self.objectToUpdate = objectToUpdate

    def __call__(self):
        returnDict = {}
        returnDict["update"]    = self.updateValue("NewValue")
        return returnDict

    def __str__(self):
        return "update starting"

    def updateValue(self, updatedValue):
        for i in range(5):
            time.sleep(1) # updating my object - time consuming with possible pid kill
            print "working... (pid=%s)" % os.getpid()

        self.objectToUpdate.accurate = updatedValue
        return self.objectToUpdate




if __name__ == '__main__':
    taskQueue   = multiprocessing.JoinableQueue()
    resultQueue     = multiprocessing.Queue()
    newProcess  = NewParallelProcess(taskQueue, resultQueue, processName="updateMyObject")
    newProcess.start()

    myObject = OldObject()  
    taskQueue.put(UpdateObject(myObject))

    # poison pill for NewParallelProcess loop and wait to finish
    taskQueue.put(None)
    taskQueue.join()

    # get back results
    results = resultQueue.get()
    print "Values have been updated"
    print "---> %s became %s" % (myObject.accurate, results["update"].accurate)

有关如何终止newProcess并继续主程序的任何建议?

嗯,做了一些修改,这就是我想要的。不确定它是否是最有效的,所以总是欢迎任何改进:)

import multiprocessing
import time, os

class NewParallelProcess(multiprocessing.Process):

    def __init__(self, taskQueue, resultQueue, processName):
        multiprocessing.Process.__init__(self)
        self.taskQueue      = taskQueue
        self.resultQueue    = resultQueue
        self.name       = processName


    def run(self):
        print "Process %s (pid = %s) added to the list of running processes" % (self.name, self.pid)
        next_task = self.taskQueue.get()

        self.taskQueue.task_done()
        self.resultQueue.put(next_task())

        return



class OldObject(object):
    def __init__(self):
        self.accurate       = "OldValue"
        self.otherValue     = "SomeOtherValue"



class UpdateObject(dict):
    def __init__(self, objectToUpdate, valueToUpdate):
        self.objectToUpdate = objectToUpdate
        self.valueToUpdate = valueToUpdate


    def __call__(self):
        returnDict = {}
        returnDict["update"]    = self.updateValue(self.valueToUpdate)
        return returnDict


    def updateValue(self, updatedValue):
        for i in range(5):
            time.sleep(1) # updating my object - time consuming with possible pid kill
            print "working... (pid=%s)" % os.getpid()

        self.objectToUpdate.accurate = updatedValue
        return self.objectToUpdate




if __name__ == '__main__':
    # queue for single process
    taskQueue   = multiprocessing.JoinableQueue()
    resultQueue     = multiprocessing.Queue()
    newProcess  = NewParallelProcess(taskQueue, resultQueue, processName="updateMyObject")
    newProcess.start()

    myObject = OldObject()  
    taskQueue.put(UpdateObject(myObject, "NewValue"))


    while True:
        # check if newProcess is still alive
        time.sleep(5)
        if newProcess.is_alive() is False:
            print "Process %s (pid = %s) is not running any more (exit code = %s)" % (newProcess.name, newProcess.pid, newProcess.exitcode)
            break


    if newProcess.exitcode == 0:
        print "ALL OK"
        taskQueue.join()

        # get back results
        print "NOT KILLED"

        results = resultQueue.get()
        print "Values have been updated"
        print "---> %s became %s" % (myObject.accurate, results["update"].accurate)


    elif newProcess.exitcode == 1:
        print "ended with error in function"
        print "KILLED"
        for i in range(5):
            time.sleep(1)
            print "i continue"


    elif newProcess.exitcode == -15 or newProcess.exitcode == -9:
        print "ended with kill signal %s" % newProcess.exitcode
        print "KILLED"
        for i in range(5):
            time.sleep(1)
            print "i continue"


    else:
        print "no idea what happened"
        print "KILLED"
        for i in range(5):
            time.sleep(1)
            print "i continue"

0 个答案:

没有答案