我最近試圖將我的溼度傳感器測得的數據存儲到我的MYSQL數據庫中。我已經編寫了必要的C++程序,從傳感器獲取數據,將其存儲在我的MYSQL數據庫中,並獲取當前的UnixTime。獲得每秒傳感器的值C++
但是,我想每秒存儲一次數據,並且認爲使用線程似乎並不是這個問題的簡單解決方案。我也不希望MYSQL自動插入UnixTime。我想繼續使用我的C++程序。
有沒有人知道一個更簡單的方法來存儲每秒鐘的數據與necesarry UnixTime使用C++?
我最近試圖將我的溼度傳感器測得的數據存儲到我的MYSQL數據庫中。我已經編寫了必要的C++程序,從傳感器獲取數據,將其存儲在我的MYSQL數據庫中,並獲取當前的UnixTime。獲得每秒傳感器的值C++
但是,我想每秒存儲一次數據,並且認爲使用線程似乎並不是這個問題的簡單解決方案。我也不希望MYSQL自動插入UnixTime。我想繼續使用我的C++程序。
有沒有人知道一個更簡單的方法來存儲每秒鐘的數據與necesarry UnixTime使用C++?
線程實際上是一個整潔的解決方案的後臺任務。考慮這個例子:
#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_until
改用sleep_for
。
您可以獲得正確的喚醒時間一次。然後在循環中做任何你需要做的工作。然後通過睡覺醒來,直到比最後一次醒來時間長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
,因爲您不知道其他工作需要多長時間。
我遇到了一個問題,當涉及到system_clock :: now()+ 1s我總是得到錯誤無法找到數字文字操作符 – JayJay
@JayJay:啊,這意味着你使用的是C++ 14之前的標準。不是問題。用秒{1}代替1秒,你會很開心。沒有功能或性能差異。只是C++ 14添加了語法糖。 –
你不需要一個明確的線程 - 每次閱讀之間就睡一秒鐘。你可以用std :: time()獲得時間。 –
但是如果我的代碼更長,該怎麼辦?比方說,在我向傳感器索取數據之前,我得到了200行代碼。如果睡1秒,那麼我不會每秒收到一個值。有沒有辦法打斷一個人退出C?所以,每當UixTime變化,我問我的傳感器的數據,並將其寫入我的數據庫? – JayJay
如果你在* NIX下工作,有什麼反對'std :: threads'或甚至是一個老式的[fork](https://linux.die.net/man/2/fork)?這是在後臺做事情的標準方式。 – Oncaphillis