我最近试图将我的湿度传感器测量的数据存储到我的MYSQL数据库中。我已经编写了必要的C ++程序,从传感器获取数据,将其存储在我的MYSQL数据库中,并获得当前的UnixTime。
但是,我想每秒存储一次数据,并认为使用线程似乎不是解决此问题的简洁方法。我也不希望MYSQL自动插入UnixTime。我想继续使用我的C ++程序。
是否有人知道使用C ++每秒使用necesarry UnixTime存储数据的更简单方法?
答案 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();
}