每秒获取传感器的值 C++
getting value of sensor each second c++
我最近试图将我的湿度传感器测量的数据存储到我的 MYSQL 数据库中。我已经编写了必要的 C++ 程序,从传感器获取数据,将其存储在我的 MYSQL 数据库中,并获取当前的 UnixTime。
但是,我想每秒存储数据,并且认为使用线程似乎不是解决此问题的好方法。我也不希望 MYSQL 自动插入 UnixTime。为此,我想继续使用我的 C++ 程序。
有人知道使用 C++ 以必要的 UnixTime 每秒存储数据的更简单方法吗?
线程实际上是后台任务的巧妙解决方案。考虑这个例子:
#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();
}
我也会使用线程来解决这个问题。但是,我不会依赖一个工作线程。如果您的过程花费超过 1 秒的时间到 运行,会发生什么情况?
相反,我会创建一组工作线程。让每个线程等待 std::condition_variable
。这样你就不会拉你的线程的状态,而是依赖条件变量在它们在某个工作队列中工作时得到通知。
有一个专用线程就可以了。但是这里有一种方法可以在没有专用线程的情况下做到这一点。而且这种技术也可以与专用线程一起使用。
底线是:
不要为这个任务使用 sleep_for
改用sleep_until
。
您可以获得一次正确的唤醒时间。然后在循环中做任何你需要做的工作。并且下次醒来时睡到比上次醒来时间长 1s(而不是睡 1s)。
注意上面描述中的英文:"sleep until" vs "sleep for".
下面是具体化的代码:
#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 时间戳。但是上面的 take-home 点是用 system_clock::now()
设置 time_point
wakeup
一次,然后在每次迭代时简单地增加 1s
并使用 this_thread::sleep_until
睡到 time_point
。只要你的其他工作不超过1s,这个程序就会可靠地每秒输出一次数据:
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()
放在另一个线程中,那也没关系。但是要在另一个线程(仍然必须做其他工作)中保持准确的 per/sec 报告,请使用 sleep_until
而不是 sleep_for
因为您不知道其他工作需要多长时间.
我最近试图将我的湿度传感器测量的数据存储到我的 MYSQL 数据库中。我已经编写了必要的 C++ 程序,从传感器获取数据,将其存储在我的 MYSQL 数据库中,并获取当前的 UnixTime。
但是,我想每秒存储数据,并且认为使用线程似乎不是解决此问题的好方法。我也不希望 MYSQL 自动插入 UnixTime。为此,我想继续使用我的 C++ 程序。
有人知道使用 C++ 以必要的 UnixTime 每秒存储数据的更简单方法吗?
线程实际上是后台任务的巧妙解决方案。考虑这个例子:
#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();
}
我也会使用线程来解决这个问题。但是,我不会依赖一个工作线程。如果您的过程花费超过 1 秒的时间到 运行,会发生什么情况?
相反,我会创建一组工作线程。让每个线程等待 std::condition_variable
。这样你就不会拉你的线程的状态,而是依赖条件变量在它们在某个工作队列中工作时得到通知。
有一个专用线程就可以了。但是这里有一种方法可以在没有专用线程的情况下做到这一点。而且这种技术也可以与专用线程一起使用。
底线是:
不要为这个任务使用 sleep_for
改用sleep_until
。
您可以获得一次正确的唤醒时间。然后在循环中做任何你需要做的工作。并且下次醒来时睡到比上次醒来时间长 1s(而不是睡 1s)。
注意上面描述中的英文:"sleep until" vs "sleep for".
下面是具体化的代码:
#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 时间戳。但是上面的 take-home 点是用 system_clock::now()
设置 time_point
wakeup
一次,然后在每次迭代时简单地增加 1s
并使用 this_thread::sleep_until
睡到 time_point
。只要你的其他工作不超过1s,这个程序就会可靠地每秒输出一次数据:
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()
放在另一个线程中,那也没关系。但是要在另一个线程(仍然必须做其他工作)中保持准确的 per/sec 报告,请使用 sleep_until
而不是 sleep_for
因为您不知道其他工作需要多长时间.