随时使用Python多处理



我想在python中写入一个可以在给定时间段内运行某种算法的类,然后停止并返回其发现的最上调的值直到超时。

作为一个例子,我写了一个简单的课程,以查找向量中的最大值:

import time, multiprocessing
class AnytimeAlgorithm:
    def __init__(self, vector):
        self.vector = vector
        self.result = 0
    def update_forever(self):
        while True:
            i = random.randint(0, len(self.vector) - 1)
            if self.vector[i] > self.result:
                self.result = self.vector[i]
                print("self", self, "result", self.result)
    def result_after(self, seconds):
        p = multiprocessing.Process(target=self.update_forever, name="update_forever", args=())
        p.start()
        p.join(seconds)
        if p.is_alive():
            p.terminate()
        p.join()
        print("self", self, "final result", self.result)
        return self.result

if __name__ == "__main__":
    import random, numpy as np
    vector = np.random.rand(10000000)
    maximizer = AnytimeAlgorithm(vector)
    print(maximizer.result_after(0.01))

当我运行此类时,它表明,正如预期的那样,结果随时间增加。但是,返回值始终为0!这是一个典型的输出:

self <__main__.AnytimeAlgorithm object at 0x7f8e94de1cf8> result 0.420804014071
self <__main__.AnytimeAlgorithm object at 0x7f8e94de1cf8> result 0.444555804935
self <__main__.AnytimeAlgorithm object at 0x7f8e94de1cf8> result 0.852844624467
self <__main__.AnytimeAlgorithm object at 0x7f8e94de1cf8> result 0.915336332491
self <__main__.AnytimeAlgorithm object at 0x7f8e94de1cf8> result 0.964438367823
self <__main__.AnytimeAlgorithm object at 0x7f8e94de1cf8> result 0.975029317702
self <__main__.AnytimeAlgorithm object at 0x7f8e94de1cf8> result 0.975906346116
self <__main__.AnytimeAlgorithm object at 0x7f8e94de1cf8> result 0.987784181209
self <__main__.AnytimeAlgorithm object at 0x7f8e94de1cf8> result 0.996998726143
self <__main__.AnytimeAlgorithm object at 0x7f8e94de1cf8> result 0.999480015562
self <__main__.AnytimeAlgorithm object at 0x7f8e94de1cf8> result 0.999798469992
self <__main__.AnytimeAlgorithm object at 0x7f8e94de1cf8> final result 0

我的错误是什么?

当您在Python中使用多处理时,它实际上会创建一个新的独立Python过程,并运行您要求的任何内容。简化了API的事实,因此看起来,多线程不应该使您感到困惑。在主过程中,您创建一个AnytimeAlgorithm对象。然后,您创建一个运行功能的Process;这将创建一个新的过程并复制解释器的状态,因此您在新过程中也可以使用AnytimeAlgorithm的副本,可以使用。但是,这两个对象不相同,它们甚至都不在同一过程中生活,因此它们无法(直接(共享任何信息。您对新过程中对象进行的更改仅影响该过程中的对象副本,而不是原始过程中的对象。

您可以检查有关如何在主过程和产生的文档之间共享信息的文档,例如使用管道,队列或共享内存,这可能是一个不错的选择:

import multiprocessing
import random
import numpy as np
class AnytimeAlgorithm:
    def __init__(self, vector):
        self.vector = vector
        self.result = multiprocessing.Value('d', 0.0)
    def update_forever(self):
        while True:
            i = random.randint(0, len(self.vector) - 1)
            if self.vector[i] > self.result.value:
                self.result.value = self.vector[i]
                print("self", self, "result", self.result.value)
    def result_after(self, seconds):
        p = multiprocessing.Process(target=self.update_forever, name="update_forever", args=())
        p.start()
        p.join(seconds)
        if p.is_alive():
            p.terminate()
        p.join()
        print("self", self, "final result", self.result.value)
        return self.result.value

if __name__ == "__main__":
    import random, numpy as np
    vector = np.random.rand(10000000)
    maximizer = AnytimeAlgorithm(vector)
    print(maximizer.result_after(0.1))

输出:

self <__mp_main__.AnytimeAlgorithm object at 0x0000017D26AB7898> result 0.01491873361800522
self <__mp_main__.AnytimeAlgorithm object at 0x0000017D26AB7898> result 0.060776471658675835
self <__mp_main__.AnytimeAlgorithm object at 0x0000017D26AB7898> result 0.7476611733129928
self <__mp_main__.AnytimeAlgorithm object at 0x0000017D26AB7898> result 0.9468162088782311
self <__mp_main__.AnytimeAlgorithm object at 0x0000017D26AB7898> result 0.9531978645650057
self <__mp_main__.AnytimeAlgorithm object at 0x0000017D26AB7898> result 0.9992671080742871
self <__mp_main__.AnytimeAlgorithm object at 0x0000017D26AB7898> result 0.999293465561661
self <__mp_main__.AnytimeAlgorithm object at 0x0000017D26AB7898> result 0.9996894825552965
self <__mp_main__.AnytimeAlgorithm object at 0x0000017D26AB7898> result 0.9998511378366163
self <__mp_main__.AnytimeAlgorithm object at 0x0000017D26AB7898> result 0.999933119926922
self <__main__.AnytimeAlgorithm object at 0x00000195FBDC7908> final result 0.999933119926922
0.999933119926922

请注意,由于过程间同步访问,使用Value具有额外的开销。阅读文档,以了解锁定如何为此课程工作,并考虑以最小化对共享资源的访问的方式编写算法(例如,使用每个计算末尾编写的时间局部变量(。

相关内容

  • 没有找到相关文章

最新更新