【问题标题】:Python Multiprocessing VariablePython 多处理变量
【发布时间】:2021-03-12 06:26:54
【问题描述】:

我基本上需要将变量DR全局化

我创建了一个名为 DR 的变量,并在函数之外将其设置为 0。然后函数(用于确定是否有东西进入或离开房间)当有人进入时将 DR 加 1,当有人离开时将 1 带走。

from multiprocessing import Process, Value
import multiprocessing
DR=0

def loop_out():
    global DR
    while True:
   
        # Read the sensor data
        light2_level = ReadChannel(light2_channel)  
        light1_level = ReadChannel(light1_channel)
        # Print out results
        if light1_level>650:
            #print("Light1: {} ({}V)".format(light1_level))
            if light2_level>650:
                print ("---GOING OUT---")
                DR-=1
                print(DR)
            time.sleep(1)
   
def loop_in():
    global DR
    while True:
   
        # Read the sensor data
        light2_level = ReadChannel(light2_channel)
        light1_level = ReadChannel(light1_channel)
        if light2_level>650:
            #print("Light2 : {} ({}V)".format(light2_level))
            if light1_level>650:
                print("---GOING IN---")
                DR+=1
                print(DR)
            time.sleep(1)

#This next part executes the two functions in multi-processing
if __name__ == '__main__':
    p1=Process(target=loop_out)
    p1.start()
    p2=Process(target=loop_in)
    p2.start()

问题是,函数外部的 DR 值保持为 0,而在函数内部,“in”函数随着人的进入继续增加,而“out”函数内部随着人的离开继续减少,因此您会收到输出下面:

*someone enters"
GOING IN
People in room: 1
*someone enters"
GOING IN
People in room: 2 
*someone leaves"
GOING OuT
People in room: -1
*someone enters"
GOING IN
People in room: 3
*someone enters"
GOING OuT
People in room: -2

我需要在全局范围内更改 DR,以便我可以根据房间内的人数采取行动。我也尝试在函数内部创建新变量并在外部对它们进行添加,但是由于多处理,它们在函数外部不存在。 我希望这是有道理的,请帮忙。

【问题讨论】:

  • 根本问题是multiprocessing 使用不共享内存的单独进程。但是,解决方案不一定是全局共享值(这是可能的),而是传递给每个工作人员的一些共享值。你确定你想要一个全局值吗?
  • 这不是必需品,不。我只需要它工作。你知道我怎样才能让它工作吗?谢谢

标签: python multiprocessing python-multiprocessing


【解决方案1】:

使用multiprocessing.Value 作为函数的参数,并使用multiprocessing.Lock 保护它,因为它是共享资源:

import multiprocessing
import time

# BEGIN MOCK
light1_channel = None
light2_channel = None


def ReadChannel(channel):
    from random import randint
    return randint(600, 700)
# END MOCK


def loop_out(DR, lock):
    while True:

        # Read the sensor data
        light2_level = ReadChannel(light2_channel)
        light1_level = ReadChannel(light1_channel)
        # Print out results
        if light1_level > 650:
            # print("Light1: {} ({}V)".format(light1_level))
            if light2_level > 650:
                print ("---GOING OUT---")
                lock.acquire()
                DR.value -= 1
                lock.release()
                print(DR.value)
            time.sleep(1)


def loop_in(DR, lock):
    while True:

        # Read the sensor data
        light2_level = ReadChannel(light2_channel)
        light1_level = ReadChannel(light1_channel)
        if light2_level > 650:
            # print("Light2 : {} ({}V)".format(light2_level))
            if light1_level > 650:
                print("---GOING IN---")
                lock.acquire()
                DR.value += 1
                lock.release()
                print(DR.value)
            time.sleep(1)


# This next part executes the two functions in multi-processing
if __name__ == '__main__':
    DR = multiprocessing.Value('i', 0)
    lock = multiprocessing.Lock()
    p1 = multiprocessing.Process(target=loop_out, args=(DR, lock))
    p1.start()
    p2 = multiprocessing.Process(target=loop_in, args=(DR, lock))
    p2.start()

编辑:这是另一个没有 Lock 实例的版本,因为正如宫城先生在 cmets 中所提到的,Value 实例已经默认包含一个锁:

import multiprocessing
import time

# BEGIN MOCK
light1_channel = None
light2_channel = None


def ReadChannel(channel):
    from random import randint
    return randint(600, 700)
# END MOCK


def loop_out(DR):
    while True:
        # Read the sensor data
        light2_level = ReadChannel(light2_channel)
        light1_level = ReadChannel(light1_channel)
        # Print out results
        if light1_level > 650:
            # print("Light1: {} ({}V)".format(light1_level))
            if light2_level > 650:
                print ("---GOING OUT---")
                with DR.get_lock():
                    DR.value -= 1
                print(DR.value)
            time.sleep(1)


def loop_in(DR):
    while True:
        # Read the sensor data
        light2_level = ReadChannel(light2_channel)
        light1_level = ReadChannel(light1_channel)
        if light2_level > 650:
            # print("Light2 : {} ({}V)".format(light2_level))
            if light1_level > 650:
                print("---GOING IN---")
                with DR.get_lock():
                    DR.value += 1
                print(DR.value)
            time.sleep(1)


# This next part executes the two functions in multi-processing
if __name__ == '__main__':
    DR = multiprocessing.Value('i', 0)
    p1 = multiprocessing.Process(target=loop_out, args=(DR,))
    p1.start()
    p2 = multiprocessing.Process(target=loop_in, args=(DR,))
    p2.start()

【讨论】:

  • 非常感谢!我一回家就试试。
  • 好吧,佛罗多又帮助了甘道夫……;)
  • A multiprocessing.Value 默认情况下已经同步。不需要单独的锁。
  • @MisterMiyagi 谢谢你的评论,我用另一个没有额外锁实例的解决方案编辑了我的答案。
  • 哈哈,霍比特人真是了不起的生物;)我真的不能感谢你,你已经减轻了我​​的压力。万事如意
猜你喜欢
  • 2020-06-12
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-26
  • 1970-01-01
  • 2015-06-08
  • 2012-06-28
相关资源
最近更新 更多