英文:
How to break an infinite loop in module from main script?
问题
我正在尝试在我的Python主脚本模块中使用while
循环。是否有一种方法可以在不使用多进程的情况下实现这一点?因为我已经看到多进程在模块中不可行,因为Windows不支持fork
。
所以我正在尝试将while
循环放入start_capture
或measure
函数中,然后启动measure
函数作为进程(如果需要),这样看起来可能是这样的:
# 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:
# 进行操作
或者像这样:
# 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:
# 进行操作
def stop_capture():
something = false
但主要问题是,我希望在主脚本中想要停止测量时能够打破循环。任何建议或帮助将不胜感激。
英文:
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.
答案1
得分: 0
你可能尝试过使用break语句来退出循环吗?它会像这样:
while True:
#做一些事情
break
这将使你退出循环并继续执行其余的代码。
或者,你也可以使用.exit()
或sys.exit()
。
英文:
Have you possibly tried a break statement to exit the loop? It would go something like this:
while True:
#do stuff
break
This would cause you to leave the loop and continue with the rest of the code.
Alternatively you can use .exit()
or sys.exit()
答案2
得分: 0
可以,你仍然可以在Windows中使用多进程。通常情况下,你只需要确保在启动任何在全局范围内执行直接或间接创建子进程的语句的主要脚本中,这些语句都被包含在一个 if __name__ == '__main__':
块中。还建议将不需要用于初始化任何子进程的全局范围内的语句也放在这样的块中。
但是,在 sensorHandler.py 中还有其他问题。首先,在 stop_capture
和 measure
方法中,你没有使用名称为 self 的必需参数。其次,在 SensorHandler
类中的 self.sensors
是一个常规的 list
实例(可能命名不当)。当创建子进程并向该列表添加内容时,它是添加到了位于为子进程创建的新地址空间中的 SensorHandler
实例的副本。因此,按照当前的编码方式,主程序无法检索到此列表。一种解决方法是使用受管理的列表,可以跨进程共享。但要注意,对该列表的每个操作都比使用常规列表要慢。因此,我建议主进程创建受管理的列表并使用它来实例化 SensorHandler
实例,如下所示:
在你的情况下,mainScript.py 将如下所示:
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)
然后,我会将 sensorHandler.py 编码如下:
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)
在终止几秒钟后打印:
[0, 1, 2]
请注意,我已将属性 sensors
重命名为 measurements
,因为你可能是在该列表中添加传感器读数或测量数据,而不是传感器本身。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论