每秒获得传感器的价值c ++

时间:2017-01-22 21:09:23

标签: c++ mysql database unix-timestamp

我最近试图将我的湿度传感器测量的数据存储到我的MYSQL数据库中。我已经编写了必要的C ++程序,从传感器获取数据,将其存储在我的MYSQL数据库中,并获得当前的UnixTime。

但是,我想每秒存储一次数据,并认为使用线程似乎不是解决此问题的简洁方法。我也不希望MYSQL自动插入UnixTime。我想继续使用我的C ++程序。

是否有人知道使用C ++每秒使用necesarry UnixTime存储数据的更简单方法?

3 个答案:

答案 0 :(得分:1)

我也会使用线程来解决这个问题。但是,我不会依赖一个工作线程。如果你的过程花费的时间超过1秒,会发生什么?

相反,我会创建一组工作线程。让每个线程等待std::condition_variable。这样,您就不会提取线程的状态,而是依赖条件变量在一些工作队列中工作后得到通知。

答案 1 :(得分:1)

拥有专用线程很好。但这是一种没有专用线程的方法。此技术也可以与专用线程一起使用。

底线是:

请勿将sleep_for用于此任务

改为使用sleep_until

你可以获得一次适当的唤醒时间。然后在循环中做你需要做的任何工作。然后通过睡觉醒来比上次醒来时间长1秒(而不是睡觉1秒)。

请注意上述说明中的英语:“睡觉直到”与“睡觉为”。

以下是使这个具体化的代码:

#include "date.h"
#include <iomanip>
#include <iostream>
#include <random>
#include <thread>

std::mt19937_64 eng;

void
do_other_work()
{
    using namespace std;
    using namespace std::chrono;
    static uniform_int_distribution<> dist{2, 600};
    this_thread::sleep_for(milliseconds{dist(eng)});
}

std::pair<double, date::sys_seconds>
get_humidity()
{
    using namespace std;
    using namespace std::chrono;
    using namespace date;
    static uniform_real_distribution<> dist;
    return {dist(eng), round<seconds>(system_clock::now())};
}

int
main()
{
    using namespace std;
    using namespace std::chrono;
    using namespace date;
    cout << fixed << setprecision(2);
    auto wakeup = system_clock::now() + 1s;
    while (true)
    {
        auto data = get_humidity();
        cout << data.first << " : " << data.second << '\n';
        do_other_work();
        this_thread::sleep_until(wakeup);
        wakeup += 1s;
    }
}

我添加了header-only library "date.h"只是为了便于格式化当前的UnixTime时间戳。但上面的回程点是用time_point设置wakeup system_clock::now()一次,然后在每次迭代时将其递增1s并使用this_thread::sleep_until睡到那个time_point。只要您的其他工作不超过1秒,该程序将每秒可靠地输出一次数据:

0.79 : 2017-01-23 02:06:21
0.40 : 2017-01-23 02:06:22
0.02 : 2017-01-23 02:06:23
0.27 : 2017-01-23 02:06:24
0.14 : 2017-01-23 02:06:25
0.86 : 2017-01-23 02:06:26
...

如果你想把get_humidity()放在另一个帖子里,那还可以。但是要在其他线程中保留准确的每秒报告(仍然必须执行其他工作),请使用sleep_until而不是sleep_for,因为您不知道其他工作需要多长时间。< / p>

答案 2 :(得分:0)

线程实际上是后台任务的简洁解决方案。考虑这个例子:

#include <iostream>
#include <thread>
#include <chrono>

void everySecondTask() {
  while (true) {
    // Do actual work here, e.g. get sensor data and write to db
    std::cout << "second passed" << std::endl;

    std::this_thread::sleep_for(std::chrono::seconds(1));
  }
}

int main() {
  // operations and sleep in everySecondTask is done in different thread, code
  // in main is not paused.
  std::thread background(everySecondTask);

  // do you 200 lines of code here, while task is called every second

  background.join();
}