I basically need to globalise the variable DR
I've made a variable called DR and set it to 0 outside the functions. Then the functions (which determine if something is entering or exiting the room) add 1 to DR when someone goes in and takes 1 away when someone leaves.
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()
The problem is, the value of DR outside the functions remains as 0, and inside the "in" function continues to increase as people enter, and inside the "out" function continues to decrease as people leave so you receive the output below:
*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
I need to make DR change globally so that I can act on the amount of people inside the room. I have also tried making new variables inside the functions and doing addition on them outside however, due to the multiprocessing they do not exist outside the function. I hope this makes sense, please help.
Use a multiprocessing.Value
as argument of your functions, and protect it with a multiprocessing.Lock
since it is a shared resource:
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()
Edit: Here is another version without Lock
instance since, as mentioned in the comments by Mister Miyagi, the Value
instance already has a lock included by default:
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()