2017-01-22 90 views
0

我最近試圖將我的溼度傳感器測得的數據存儲到我的MYSQL數據庫中。我已經編寫了必要的C++程序,從傳感器獲取數據,將其存儲在我的MYSQL數據庫中,並獲取當前的UnixTime。獲得每秒傳感器的值C++

但是,我想每秒存儲一次數據,並且認爲使用線程似乎並不是這個問題的簡單解決方案。我也不希望MYSQL自動插入UnixTime。我想繼續使用我的C++程序。

有沒有人知道一個更簡單的方法來存儲每秒鐘的數據與necesarry UnixTime使用C++?

+0

你不需要一個明確的線程 - 每次閱讀之間就睡一秒鐘。你可以用std :: time()獲得時間。 –

+0

但是如果我的代碼更長,該怎麼辦?比方說,在我向傳感器索取數據之前,我得到了200行代碼。如果睡1秒,那麼我不會每秒收到一個值。有沒有辦法打斷一個人退出C?所以,每當UixTime變化,我問我的傳感器的數據,並將其寫入我的數據庫? – JayJay

+0

如果你在* NIX下工作,有什麼反對'std :: threads'或甚至是一個老式的[fork](https://linux.die.net/man/2/fork)?這是在後臺做事情的標準方式。 – Oncaphillis

回答

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(); 
} 
1

我也會使用線程來解決這個問題。但是,我不會依賴一個工作線程。如果您的流程需要1秒以上的運行時間會發生什麼?

相反,我會創建一組工作線程。讓每個線程等待std::condition_variable。這樣你就不會拉你的線程狀態,而是依賴條件變量在一些工作隊列中工作後得到通知。

1

有一個專用的線程是好的。但是,這是一種無需專用線程的方法。而且這種技術也可以用於專用線程。

的底線是:

不要爲這個任務

使用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_pointwakeup設置爲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,因爲您不知道其他工作需要多長時間。

+0

我遇到了一個問題,當涉及到system_clock :: now()+ 1s我總是得到錯誤無法找到數字文字操作符 – JayJay

+0

@JayJay:啊,這意味着你使用的是C++ 14之前的標準。不是問題。用秒{1}代替1秒,你會很開心。沒有功能或性能差異。只是C++ 14添加了語法糖。 –