2017-01-22 1 views
0

최근 내 습도 센서로 측정 한 데이터를 MYSQL 데이터베이스에 저장하려고합니다. 나는 이미 센서에서 데이터를 가져와 필요한 MYSQL 데이터베이스에 저장하고 현재 UnixTime을 얻는 데 필요한 C++ pgramm을 프로그래밍했습니다.센서의 값을 매초마다 얻음 C++

그러나 저는 매 초마다 데이터를 저장하고 스레드를 사용하는 것이이 문제에 대한 깔끔한 해결책으로 보이지 않는다고 생각합니다. 또한 MYSQL에 UnixTime을 자동으로 삽입하는 것을 원하지 않습니다. C++ 프로그램을 계속 사용하고 싶습니다.

누구나 C++을 사용하여 necesarry UnixTime을 사용하여 매 초마다 데이터를 저장하는 더 쉬운 방법을 알고 있습니까?

+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 초 이상 깨면 일어나십시오.

위의 설명에서 "sleep until"과 "sleep for"을 유의하십시오. 나는 header-only library "date.h" 그냥 쉽게 현재 UnixTime 타임 스탬프를 포맷 할 수 있도록 추가 한

#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; 
    } 
} 

:

다음은이 콘크리트를 만들기 위해 코드입니다. 위의 홈 지점은 system_clock::now()으로 time_pointwakeup을 한 번 설정 한 다음 각 반복마다 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()을 넣어하려는 경우, 그것은 여전히 ​​괜찮습니다. 그러나 다른 작업을 수행해야하는 다른 스레드에서 정확한 per/sec 보고서를 유지하려면 sleep_for 대신 sleep_until을 사용하십시오. 다른 작업에 소요되는 시간을 모르기 때문에이 값을 사용하십시오.

+0

system_clock :: now() + 1s와 관련하여 문제가 발생했습니다. 숫자 리터럴 연산자를 찾을 수없는 오류가 항상 발생합니다. – JayJay

+0

@JayJay : 아, 즉 C++ 14 이전의 표준을 사용하고 있다는 의미입니다. 문제가 아니다. 1 초를 {1} 초로 대체하면 도움이 될 것입니다. 기능적 또는 성능상의 차이는 없습니다. Just C++ 14는 구문 론적 인 설탕을 추가했습니다. –

관련 문제