I'm trying to have a while
loop in my module for a main script Python. Is there a way to do this without using multiprocessing, as I've seen that multiprocessing isn't viable in modules due to Windows not having fork
support.
So I'm trying to fit the while
loop inside either the start_capture
or measure
function, and then start the measure
function as process (if needed), so that it would look either something like this:
#mainScript.py
from sensorHandler import SensorHandler
sensors = SensorHandler()
sensors.start_capture()
sensors.stop_capture()
#sensorHandler.py
class SensorHandler():
def __init__ (self):
self.sensors = []
def start_capture(self):
process = Process(target=measure,args=(self.sensors,))
process.start()
def stop_capture():
process.terminate()
def measure(sensors):
while True:
#do stuff
Or like this:
#mainScript.py
from sensorHandler import SensorHandler
sensors = SensorHandler()
sensors.start_capture()
sensors.stop_capture()
#sensorHandler.py
class SensorHandler():
def __init__ (self):
self.sensors = []
def start_capture(self):
while something:
#do stuff
def stop_capture():
something = false
But the main point is that I want to break the loop from the main script when I want it to stop measuring. Any recommendations or help would be greatly appreciated.
Yes, you can still use multiprocessing in Windows. In general, you just need to ensure that within the main script that you are launching any statement at global scope that directly or indirectly executes a statement that creates a child process is wrapped in an if __name__ == '__main__':
block. It is also advisable to place in such a block any statement at global scope that is not required for the initialization of any child process.
But you have other issues with sensorHandler.py. First, you do not have required arguments named self in the methods stop_capture
and measure
. Second, self.sensors
in class SensorHandler
is a regular list
instance (and perhaps not well-named). When the child process is created and presumably appends to this list, it is doing so to a copy of the SensorHandler
instance that resides in the new address space created for the child process. So, as currently coded, there is no way for the main program to retrieve this list. One solution is to use a managed list, which is shareable across processes. But be aware that each operation on this list is slower that if you were using a regular list. So I would have the main process create the managed list and use it to instantiate the SensorHandler
instance as follows:
In your case, mainScript.py will look like:
if __name__ == '__main__':
from sensorHandler import SensorHandler
from multiprocessing import Manager
with Manager() as manager:
measurements = manager.list()
sensor_handler = SensorHandler(measurements)
sensor_handler.start_capture()
input('Hit enter to stop capturing... ')
sensor_handler.stop_capture()
print(measurements)
Then I would code sensorHandler.py as follows:
from multiprocessing import Process
import time
class SensorHandler():
def __init__ (self, measurements):
self.measurements = measurements
def start_capture(self):
self.process = Process(target=self.measure)
self.process.start()
def stop_capture(self):
self.process.terminate()
def measure(self):
for i in range(100):
self.measurements.append(i)
time.sleep(1)
Prints (when terminated after a few seconds):
[0, 1, 2]
Note that I have renamed attribute sensors
to measurements
since presumably you are appending to this list sensor readings or measurements and not sensors.