1

我的 Linux C++ 应用程序定期读取传感器数据。读取是通过简单的文件 I/O 操作完成的(操作系统正在写入文件,应用程序正在读取该文件)。关于我的平台的一些信息:

  • 我有带超线程的单核处理器
  • 传感器数据更新频率为1秒
  • 应用程序 GUI 在主线程中运行,不应被阻塞

我考虑了两种读取传感器数据的方法:

  • 在主应用程序线程中运行的计时器
  • 具有无限循环的独立线程,它读取传感器数据然后休眠

哪种方法更有意义,还有其他选择吗?两种解决方案的成本是多少(例如,在第一种方法中阻塞主线程或在第二种方法中进行上下文切换)?

4

5 回答 5

2

我对您的应用程序或硬件一无所知,但这里有几点需要考虑:

  • 如果使用线程,则必须创建某种通信通道来告诉主线程数据已更新。通常这将是一个 pipe(),因为信号本质上是不可靠的,并且条件锁不适用于 I/O 多路复用(即 select()/poll())。
  • 可以不阻塞地获取整组数据吗?如果是这样,那么在主线程中阅读它可能会更容易。但是,如果您的读取可能会阻塞,您可能需要更多“跟踪我的读取状态以将其合并到我的中央 select() 中”,而线程可以阻塞直到有更多数据可用。

因此,这两种解决方案都不会自动“更容易”做到。

对于每秒只发生一次的读取,我不会担心“上下文切换”;这无关紧要。

于 2012-09-29T10:42:20.523 回答
1

我相信,即使对于没有超线程的单核 CPU,每秒一次的上下文切换成本也不是问题,特别是考虑到应用程序在用户空间中运行,因此并不是真正的时间关键。在主线程中轮询传感器会使应用程序的逻辑复杂化。因此,我建议您为此目的启动一个线程。

于 2012-09-29T10:43:02.203 回答
1

主线程还需要做什么?如果阻塞就可以了吗?如果是这样,那么您不需要在单独的线程中执行计时器等。

如果主线程不能阻塞等待周期性计时器,则必须创建一个单独的线程。线程之间的数据通信可以通过两个线程都可以访问并通过互斥锁(查找 pthread_mutex_t)保护的对象进行,这很容易做到。

至于哪种方案更好,成本是多少,就看主线程还做了什么。但是对于这么简单的事情,任何一种方式都应该大致相同,并且上下文切换不应该影响任何事情。对性能影响最大的是读取的性能密集程度。

于 2012-09-29T10:50:26.550 回答
0

如果 Linux 驱动程序每秒读取传感器数据并将其写入设备文件,则不应在应用程序中复制计时器逻辑。在 1 秒睡眠后,您的应用程序可能仍会读取与 1 秒前相同的数据。更好的方法是有一个线程来调用设备文件上的阻塞读取。当新的传感器数据可用时,阻塞读取返回,线程可以处理数据并再次调用读取。

于 2012-09-29T13:13:56.320 回答
0

睡眠循环会扭曲时间,因为每次迭代将花费超过 1 秒的时间。计时器没有这个问题,它们是为这种情况而设计的。所以选择一个计时器。

性能方面没有区别,因为您每秒只触发一次。

于 2012-09-29T11:13:16.670 回答