首页 > 解决方案 > 在连续运行中打开线程时避免增加运行时间

问题描述

我正在做我的期末论文,我的主题是创建一个可以运行和控制卫星实验的软件。

出于这个原因,我必须在实验运行时读取多个传感器。为此,我编写了代码,以便它为每个传感器创建一个新线程(多处理可能不起作用,因为我还不知道软件将在哪个系统上运行,因此我不能说是否会有多个处理器可用)并且这些线程在软件执行其操作时一直作为守护进程运行。它运作良好,但现在我需要测试整个事情,这就是问题所在

为了正确测试软件可以采用的每条路线,我需要设置多个变量,因此会有很多测试运行(我计算出大约 17.000,但可能是错误的)。虽然最初的几次测试运行很快就结束了,但每次运行需要的时间越来越长。我稍微摆弄了一下我的代码,结果发现如果没有线程,每个测试都需要大约相同的时间。不幸的是,我不知道为什么,而且我对此事的了解非常有限。关于线程的代码如下:

这设置了每个线程的创建(sensor_list将在非测试条件下填充多个传感器)

sensor_list = [<a single sensor>]
        for sensor in sensor_list:
            thread = threading.Thread(
                target=self.store_sensor_data,
                args=[sensor, query_frequency],
                daemon=True,
                name=f"Thread_{sensor}",
            )
            self.threads.append(thread)
            thread.start()

实际处理获取和写入传感器数据的函数self.store_sensor_data如下所示:

def store_sensor_data(self, sensor, frequency):
        """Get the current reading and result from 'sensor' and store them.

        sensor (Sensor) -  the sensor whose data shall be stored
        frequency (int) - the frequency (in 1/s) at which data shall be stored
        """
        value_id = 0
        while not self.HALT:
            value_id += 1
            sensor_reading = sensor.get_reading()
            sensor_result = sensor.get_result()
            try:
                # if there already is a list for that sensor, append the data to it
                self.experiment_report.sensor_data_raw[str(sensor)].append(
                    (value_id, sensor_reading)
                )
            except KeyError:
                # if there is no list, create one containing the current sensor value
                self.experiment_report.sensor_data_raw[str(sensor)] = [
                    (value_id, sensor_reading)
                ]
            # repeat the same for the 'result'
            try:
                self.experiment_report.sensor_data[str(sensor)].append(
                    (value_id, sensor_result)
                )
            except KeyError:
                self.experiment_report.sensor_data[str(sensor)] = [
                    (value_id, sensor_result)
                ]
            time.sleep(1 / frequency)

实验完成后,我通过调用停止线程

def interrupt_sensor_data_recording(self):
        """Interrupt the storing of sensor data by ending all daemon threads.

        threads (list) - a list of currently running threads
        """
        if len(self.threads) > 0:
            self.HALT = True
            for thread in self.threads:
                if thread.is_alive():
                    logger.debug(f"Stopping thread '{thread.getName()}'")
                    thread.join()
                else:
                    thread.join()
                    logger.debug(f"Thread '{thread.getName()}' was already stopped")

现在我不确定如何停止守护线程是否合适,这可能是我问题的根源。但是也可能有一些我还不知道的暗示,在这两种情况下,如果有比我知识更多的人可以在这里帮助我,那就太好了。

提前致谢!

标签: pythonperformancetestingembeddedpython-multithreading

解决方案


推荐阅读