为啥while循环的执行速度会随时间变化?

Posted

技术标签:

【中文标题】为啥while循环的执行速度会随时间变化?【英文标题】:Why does the execution speed of the while loop change over time?为什么while循环的执行速度会随时间变化? 【发布时间】:2021-03-24 22:57:24 【问题描述】:

我们在 C 的 while 循环中遇到了时间问题。在程序的一部分中,while循环通过SPI协议从传感器接收信息并将其存储在mysql数据库中,当我们检查存储的数据时会出现问题。 例如,数据库中每秒存储 600 条数据,但在某些秒内存储的数据数量减少到 400 条,几秒钟后又恢复到每秒 600 条,以此类推。 我知道传感器的数据传输速率在固定时钟上工作并且无法更改。 但是我不知道这个问题出在哪里。

这是 c 中的 while 循环代码:

 while(1)
        

            tx_buff[0] = 0x08 ;
            tx_buff[0] = (tx_buff[0] << 1) | 1;
            tx_buff[1] = 0xFF;
            tx_buff[2] = 0xFF;
            tx_buff[3] = 0xFF;
            tx_buff[4] = 0xFF;
            tx_buff[5] = 0xFF;
            tx_buff[6] = 0xFF;
            tx_buff[7] = 0xFF;
            tx_buff[8] = 0xFF;
            tx_buff[9] = 0xFF;
            tinkerboard_set_gpio_state(24, LOW);
            tinkerboard_spi_transfer(SPI2, tx_buff, rx_buff,10, mode);
            tinkerboard_set_gpio_state(24, HIGH);
            X_unsigned = (rx_buff[1]<<16) | (rx_buff[2]<<8)| (rx_buff[3]);
            X_unsigned = X_unsigned >> 4;
            X_signed = adc24to32(X_unsigned);
            Y_unsigned = (rx_buff[4]<<16) | (rx_buff[5]<<8)| (rx_buff[6]);
            Y_unsigned = Y_unsigned >> 4;
            Y_signed = adc24to32(Y_unsigned);
            Z_unsigned = (rx_buff[7]<<16) | (rx_buff[8]<<8)| (rx_buff[9]);
            Z_unsigned = Z_unsigned >> 4;
            Z_signed = adc24to32(Z_unsigned);

printf(" X=%5.4f Y=%5.4f Z=%5.4f \n",
X_signed*0.0039,Y_signed*0.0039,Z_signed*0.0039);
sprintf(query, "INSERT INTO PO(x,y,z) VALUES(%5.4f,%5.4f,%5.4f)",
X_signed*0.0039,Y_signed*0.0039,Z_signed*0.0039);

//conect to sql
     mysql_query(conn, query);
    
        

【问题讨论】:

and stores it in a mysql database - 这是磁盘 IO(文件系统)操作吗? 如果是,那么,RT 响应就不能依赖它,因为 FS 随时可能“选择”重组,从而产生相当大的延迟。您通常应该设置一个不同的线程来执行此操作,并从您的 while 循环中将其作为消息发送到该其他线程。 您设置了多个线程,它们通过消息队列相互交互。在这里,您需要将该数据发送到将其存储到 SQL 文件中的线程。在 FS 操作需要更长时间的情况下,该线程的消息队列将变得更加填充(消息尚未处理)。然后,一旦该操作完成,队列将逐渐“恢复正常”,其中只有几条消息待处理。所以你应该确保使用足够大的消息队列,以处理偶尔的滞后。 一些 Unix 调度程序也会惩罚在过去几秒钟内获得执行时间的进程,以支持那些没有执行时间的进程。这可能会导致某种形式的处理器时间振荡。 您可以使用进程的nice 值,提高调度优先级。请参阅手册页。 【参考方案1】:

两件事。

首先,打开与您的 MySql 服务器的连接并重用它。不要为每个插入打开一个新连接:它太慢了。请记住,MySql 连接对象不是线程安全的。

其次,如果您将许多批量插入操作捆绑到单个数据库事务中,MySql 会最有效地处理批量插入操作。而且您的项目会进行批量插入。

捆绑在一起的插入操作的合适数量是 100 左右。这有助于提高 MySql 服务器的效率,因为大部分插入工作发生在事务提交时。如果您不将插入内容包装在 START TRANSACTION;COMMIT; 中,MySql 会自动提交。这意味着每次插入也是一个事务,开销会失控。

这很容易组织。首次打开连接时,将倒计时变量设置为 100,并向 MySql 发出 START TRANSACTION;

每次插入时,递减倒计时变量。当它达到零时,重置它并执行COMMIT;,然后执行另一个START TRANSACTION;

这不会把你的项目变成一个硬实时项目,但它对 MySql 开销有很大帮助。

并且,考虑在不同的主机上运行 MySql。

【讨论】:

以上是关于为啥while循环的执行速度会随时间变化?的主要内容,如果未能解决你的问题,请参考以下文章

Pytest 和覆盖率:为啥覆盖率结果会随目录结构而变化?

为啥眼图会随vref变化 ddr

6 循环

各位懂软件,的分别使用while和do…whil循环输出1—10之间的所有数字,包括1和10这题咋做

为啥在这个循环中倒计时顺序会发生变化?

java基础知识—循环结构