2017-01-22 30 views
0

私の最近の湿度センサで測定したデータをMYSQLデータベースに保存しようとしています。私はすでにセンサからデータを取得し、それをMYSQLデータベースに格納し、現在のUnixTimeを取得するのに必要なC++ pogrammをプログラムしました。センサの値を毎秒取得するC++

しかし、私は毎秒データを保存したいと思うし、スレッドを使っていると思っても、この問題の解決策はまったくないようです。私はMYSQLにUnixTimeを自動的に挿入したくありません。私はそのために私のC++プログラムを使い続けたいと思っています。

C++を使用してUnixTimeが必要な場合は、毎秒データを保存する方が簡単ですか?

+0

明示的なスレッドは必要ありません。各読み込みの間に1秒間だけスリープします。あなたは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つのワーカースレッドに依存しません。プロセスの実行に1秒以上かかる場合はどうなりますか?

代わりに、ワーカースレッドのグループを作成します。各スレッドはstd::condition_variableで待機してください。この方法では、スレッドのステータスを取得せず、条件付き変数を使用して、作業キューに入ったら通知されます。

1

専用スレッドがあれば問題ありません。しかし、ここに専用のスレッドなしでそれを行う方法があります。また、このテクニックは専用のスレッドでも使用できます。

一番下の行は次のようになります。

は、このタスク

利用代わりsleep_untilためsleep_forを使用しないでください。

適切な起床時間を1回取得できます。そして、ループの途中で何をする必要があれば、何でもしてください。そして、次の起床時間より1秒長くなるまで(1秒間スリープするのではなく)寝ることによって、次回起床する。

上記の説明の英語に注意してください: "sleep until"対 "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; 
    } 
} 

私はちょうどあなたの現在のUnixTimeのタイムスタンプをフォーマットすることを容易にするためにheader-only library "date.h"を追加しました。上記のtake-homeのポイントは、でtime_pointwakeupを1回設定してから、各繰り返しで1sを単純にインクリメントし、time_pointになるまでthis_thread::sleep_untilを使用するだけです。限り、あなたの他の仕事が1秒を超えないように、このプログラムは、1秒に1回確実にデータを出力します:あなたは別のスレッドでget_humidity()を入れたい場合は

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 
... 

、それはまだ大丈夫です。しかし、他のスレッド(他の作業を行う必要があります)内の正確なper/secレポートを維持するには、sleep_forの代わりにsleep_untilを使用してください。

+0

system_clock :: now()+ 1sのときに問題が発生しました。数値リテラル演算子を見つけることができないエラーが発生しました – JayJay

+0

@JayJay:つまり、C++ 14より前の標準を使用しています。問題ない。 1秒間に{1}秒を置き換えれば、あなたはいいですね。機能的または性能的な違いはありません。ちょうどC++ 14は構文糖を加えました。 –

関連する問題