如何在多处理中使用共享内存概念

时间:2014-09-04 06:06:23

标签: python multiprocessing

我想使用共享变量同时启动2个进程。一个将立即开始处理,另一个将等待来自第一个进程的触发器(和共享变量),以便开始处理。

我的第一个过程,计算距离,第二个过程,根据行进的距离采取不同的行动。 Distance作为参数传递,current_conveyer是共享内存变量。

以下是我的代码: -

def process1():

    current_conveyer = Value('d', 'SC1')   # also I want to know how to initialize the string values. Current it is double precision float.

    while condition:
        conveyer_type = current_conveyer.value
        S = pickle.load(open('conveyer_speed.p','rb'))[conveyer_type]
        D = S * T # speed is changing, hence calculating the speed at every instant.
        # trigger the second process. NOT create a new process
        time.sleep(0.005)

def process2(current_converyer,distance):
    while True:
        if some condition:
              current_converyer = 'SC2'
        elif some condition:
              current_converyer = 'SC3'

截至目前,我正在为每个while循环启动一个新进程。

我想为所有这些创建一个单独的进程,它将监听和共享变量。如果发送了任何触发器,那么该进程应该监听,唤醒和工作,而不是创建一个全新的进程。

我知道这可以通过队列和管道完成,但是然后使用队列和管道会破坏共享内存的目的。

我尝试单独使用队列和管道实现上面的代码,有一些时间效率问题,因此现在想要尝试共享内存变量方法。

因此,鉴于上述情况,我想知道如何保持流程监听并实现共享内存概念。

1 个答案:

答案 0 :(得分:0)

执行多处理的最简单方法是让Pool执行多个较大的作业,每个作业都将数据返回到父进程。

如果您真的想要一个'shared'变量,请创建一个Manager对象,并使用它来创建托管(共享)对象。通过这种方式,多个proc可以读取和写入不同的值,并将值传递给不同的子进程。

以下代码具有简单的“主要”代码,可以启动两个孩子然后等待它们。一个孩子醒来,将一个项目附加到托管(共享)列表,然后等待。第二个孩子等待一段时间,消耗并打印共享列表,然后睡觉。

import multiprocessing, signal, time

def producer(objlist):
    '''
    add an item to list every sec
    '''
    while True:
        try:
            time.sleep(1)
        except KeyboardInterrupt:
            return
        msg = 'ding: {:04d}'.format(int(time.time()) % 10000)
        objlist.append( msg )
        print msg


def scanner(objlist):
    '''
    every now and then, consume objlist & run calculation
    '''
    while True:
        try:
            time.sleep(3)
        except KeyboardInterrupt:
            return
        print 'items: {}'.format( list(objlist) )
        objlist[:] = []


def main():

    # create obj sharable between all processes
    manager = multiprocessing.Manager()
    my_objlist = manager.list() # pylint: disable=E1101

    multiprocessing.Process(
        target=producer, args=(my_objlist,),
    ).start()

    multiprocessing.Process(
        target=scanner, args=(my_objlist,),
    ).start()

    # kill everything after a few seconds
    signal.signal(
        signal.SIGALRM, 
        lambda _sig,_frame: manager.shutdown(),
        )
    signal.alarm(12)

    try:
        manager.join() # wait until both workers die
    except KeyboardInterrupt:
        pass


if __name__=='__main__':
    main()

输出

ding: 8392
ding: 8393
ding: 8394
ding: 8395
ding: 8396
ding: 8397