【发布时间】:2014-08-18 09:42:20
【问题描述】:
我正在尝试实现一个程序来从触觉传感器读取数据,但我遇到了 CPU 负载高的问题。我需要帮助来减少 CPU 负载。
我的设置
我正在从多个(最多 16 个)触觉传感器读取数据。传感器通过 USB 连接到我的电脑。在 Linux 中,这些设备创建虚拟串行端口:/dev/ttyACM0、/dev/ttyACM1、/dev/ttyACM2 ...
这是 dmesg 告诉我的,当我插入传感器时(一个传感器的输出):
[321.998462] USB 2-2:USB 断开,设备号 3 [327.541414]usb 2-2:使用 ohci_hcd 的新全速 USB 设备编号 5 [327.998963]usb 2-2:找到新的 USB 设备,idVendor=0471,idProduct=0889 [327.998983]usb 2-2:新的 USB 设备字符串:Mfr=1,Product=2,SerialNumber=3 [327.998997] USB 2-2:产品:WTS [327.999011] USB 2-2:制造商:Weiss Robotics [327.999024]usb 2-2:序列号:0001 [328.035356] cdc_acm 2-2:1.0:此设备无法自行调用。它不是调制解调器。 [328.035424]cdc_acm 2-2:1.0:ttyACM0:USB ACM设备我使用 termios.h 中的 termios 打开串行设备。由于传感器具有二进制协议,我将设备设置为非规范并使用原始输出。传感器提供周期性采样功能,每秒将发送大约 270 帧数据。
一旦完整的帧可用,我的程序应该立即从串行设备读取并处理帧。
问题:cpu 负载过高
这就是我的代码的基本功能:
int fd = open("/dev/ttyACM0");
struct termios settings;
settings.xxx = ... // see full code for details
tcflush( fd, TCIFLUSH );
tcsetattr( fd, TCSANOW, &settings );
while(1)
{
Frame f = readCompleteFrame(fd);
processFrame(f);
}
当我将设备置于阻塞读取模式并执行我的循环时,cpu 负载达到约 15%。每个传感器都有一个单独的线程。由于我有多个传感器,每个线程将消耗一个 cpu 内核的 15%。
我使用 time 命令对程序进行了概要分析:几乎所有的 cpu 时间都花在了内核中。用户时间接近于零。
我试图解决的问题
- 我将设备置于非阻塞模式并使用来自 sys/poll.h 的轮询。 CPU 负载相同:每个传感器 15%。
- 我将设备置于非阻塞模式并使用 unistd.h 中的选择。与投票结果相同。
- 我将设备置于非阻塞模式并不断调用 read(fd);睡眠(1);直到我得到一些数据。这会使用 50% 的 CPU,但与传感器的数量无关。
完整的测试代码
我用于测试的完整代码可以在这里找到:http://pastebin.com/7dv0U2nN
【问题讨论】:
-
我想在这里看到更多像这样的初学者问题。