3

Firstly I'm an engineer, not a computer scientist, so please be gentle. I currently have a C++ program which uses MySQL++. The program also incorporates the NI Visa runtime. One of the interrupt handlers receives data (1 byte) from a USB device about 200 times a second. I would like to store this data with a time stamp on each sample on a remote server. Is this feasible? Can anyone recommend a good approach? Regards, Michael

4

4 回答 4

4

我认为对远程服务器执行 200 个事务/秒要求很多,尤其是当您考虑到这些事务将发生在必须完成其工作并快速完成的中断处理程序的上下文中时。我认为最好将您的中断处理程序与您的数据库访问分离-也许让中断处理程序将传入数据和时间戳存储到某种内存数据结构中(数组、循环链表或其他任何东西,并具有适当的同步)并有一个单独的线程等待数据结构中的数据可用,然后将其泵入数据库。我希望使中断处理程序尽可能精简和确定,并且我担心通过网络访问远程服务器的数据库会太慢 - 或者更糟,

当然,这会引发数据溢出的问题/问题,即数据进入的速度超过了将其泵入数据库的速度,并且内存中的存储结构被填满。这可能会导致数据丢失。如果你丢了一些样品有多糟糕?

于 2010-01-26T12:52:34.550 回答
1

我认为您无法通过每个值 1 个单独的插入来保持该速度,但是如果您将它们分成足够大的批次,您可以将它们全部作为一个查询发送,应该没问题。

INSERT INTO records(timestamp, value)
  VALUES(1, 2), (3, 4), (5, 6), [...], (399, 400);

只需将时间戳和值推送到缓冲区,当缓冲区大小达到 200(或其他任意数字)时,生成 SQL 并将全部发送出去。用 sprintf 构建这个字符串应该不会太慢。请注意从您的中断例程可能同时写入的数据结构中读取数据。

如果您发现此 SQL 生成由于某种原因太慢,并且没有使用 API 的更快方法(例如存储过程),那么您可能希望与数据收集同时运行它。最简单的可能是将数据通过套接字或管道流式传输到执行 SQL 生成的另一个进程。还有多线程方法,但它们更复杂且容易出错。

于 2010-01-26T13:57:09.527 回答
0

在我看来,您应该做两件事:1. 缓冲数据和 2. 每个缓冲区一个时间戳。USB 协议不是基于字节的,而是基于更多消息的。如果您正在跟踪消息,则为消息添加时间戳。

此外,数据库宁愿接收数据块或数据块,也不愿一次接收一个字节。每个事务在数据库中都有开销。要衡量效率,请将开销除以事务中的字节数。你会看到大块比大量小交易更有效。

另一种选择是将数据存储到文件中,然后使用 MySQL LOADFILE 函数将数据加载到数据库中。此外,将数据存储到缓冲区中,然后使用 MySQL C++ 连接器流将数据加载到数据库中。

于 2010-01-26T17:39:53.390 回答
0

即使您在服务器端正确缓存了多线程,也不能保证比公寓快,除非有一些奇怪的 cpu 优先级偏好。如何使用着色器并让 windows.h 中的参考值作为时间戳

于 2018-01-06T05:24:38.923 回答