C ++ Linux에서 밀리 초 시간을 얻는 C ++ - Clock ()가 제대로 작동하지 않는 것 같습니다.

StackOverflow https://stackoverflow.com/questions/588307

  •  09-09-2019
  •  | 
  •  

문제

창문에서 clock() 시간을 밀리 초로 반환하지만, 내가 작업중 인이 Linux 상자에서는 가장 가까운 1000으로 반올림하여 정밀도는 밀리 초 수준이 아닌 "두 번째"레벨에만 이루어집니다.

QT를 사용하여 솔루션을 찾았습니다 QTime 클래스, 대상을 인스턴스화하고 호출 start() 그런 다음 전화하십시오 elapsed() 밀리 초의 수를 경과합니다.

처음부터 QT와 함께 일하기 때문에 운이 좋았지 만 타사 라이브러리에 의존하지 않는 솔루션을 원합니다.

이 작업을 수행하는 표준 방법이 없습니까?

업데이트

부스트를 추천하지 마십시오 ..

Boost와 QT가 할 수 있다면 분명히 마술이 아니라 사용하는 표준이 있어야합니다!

도움이 되었습니까?

해결책

방법의 시작과 끝에서 gettimeofday를 사용한 다음 두 개의 반환 스트러크를 차이로 만들 수 있습니다. 다음과 같은 구조를 얻을 수 있습니다.

struct timeval {
  time_t tv_sec;
  suseconds_t tv_usec;
}

다른 팁

#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
    struct timeval start, end;

    long mtime, seconds, useconds;    

    gettimeofday(&start, NULL);
    usleep(2000);
    gettimeofday(&end, NULL);

    seconds  = end.tv_sec  - start.tv_sec;
    useconds = end.tv_usec - start.tv_usec;

    mtime = ((seconds) * 1000 + useconds/1000.0) + 0.5;

    printf("Elapsed time: %ld milliseconds\n", mtime);

    return 0;
}

점에 유의하시기 바랍니다 clock 하다 ~ 아니다 벽 시계 시간을 측정하십시오. 즉, 프로그램이 5 초가 걸리면 clock 반드시 5 초를 측정하지는 않지만 더 많은 스레드를 실행할 수 있으므로 실시간보다 더 많은 CPU를 소비 할 수 있습니다). 근사치를 측정합니다 CPU 시간 사용된. 차이를 보려면이 코드를 고려하십시오

#include <iostream>
#include <ctime>
#include <unistd.h>

int main() {
    std::clock_t a = std::clock();
    sleep(5); // sleep 5s
    std::clock_t b = std::clock();

    std::cout << "difference: " << (b - a) << std::endl;
    return 0;
}

내 시스템에서 출력합니다

$ difference: 0

우리가 한 모든 일은 자고 있고 CPU 시간을 사용하지 않았기 때문입니다! 그러나 사용 gettimeofday 우리는 우리가 원하는 것을 얻습니다 (?)

#include <iostream>
#include <ctime>
#include <unistd.h>
#include <sys/time.h>

int main() {
    timeval a;
    timeval b;

    gettimeofday(&a, 0);
    sleep(5); // sleep 5s
    gettimeofday(&b, 0);

    std::cout << "difference: " << (b.tv_sec - a.tv_sec) << std::endl;
    return 0;
}

내 시스템의 출력

$ difference: 5

더 정밀도가 필요하지만 원한다면 CPU 시간, 그런 다음 사용을 고려할 수 있습니다 getrusage 기능.

또한 Boost가 제공하는 도구를 권장합니다. 언급 된 부스트 타이머 또는 부스트에서 무언가를 해킹하거나 샌드 박스에 새로운 제안 된 라이브러리가 있습니다. 부스트 .Chrono: 마지막 것은 타이머를 대체 할 것이며 다음과 같은 특징이 있습니다.

  • C ++ 0X 표준 라이브러리의 시간 유틸리티 (:
    • 클래스 템플릿 duration
    • 클래스 템플릿 time_point
    • 시계 :
      • system_clock
      • monotonic_clock
      • high_resolution_clock
  • 클래스 템플릿 timer, typedefs와 함께 :
    • system_timer
    • monotonic_timer
    • high_resolution_timer
  • 프로세스 클럭 및 타이머 :
    • process_clock, 실제, 사용자 CPU 및 시스템 CPU 시간 캡처.
    • process_timer, 캡처 됨 실제, 사용자 CPU 및 시스템 CPU 시간이 경과했습니다.
    • run_timer, 편리한보고 | Process_TIMER | 결과.
  • C ++ 0X 표준 라이브러리의 컴파일 타임 합리적 산술.

여기 소스가 있습니다 기능 목록의

나는 a Timer 수업을 기반으로합니다 CTT의 답변. 다음과 같은 방식으로 사용할 수 있습니다.

Timer timer = Timer();
timer.start();
/* perform task */
double duration = timer.stop();
timer.printTime(duration);

구현은 다음과 같습니다.

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
using namespace std;

class Timer {
private:

    timeval startTime;

public:

    void start(){
        gettimeofday(&startTime, NULL);
    }

    double stop(){
        timeval endTime;
        long seconds, useconds;
        double duration;

        gettimeofday(&endTime, NULL);

        seconds  = endTime.tv_sec  - startTime.tv_sec;
        useconds = endTime.tv_usec - startTime.tv_usec;

        duration = seconds + useconds/1000000.0;

        return duration;
    }

    static void printTime(double duration){
        printf("%5.6f seconds\n", duration);
    }
};

오래된 유엔에 휴대 할 수있는 코드가 필요하지 않은 경우 clock_gettime ()을 사용할 수 있습니다. 나노 초 (프로세서가 해당 해상도를 지원하는 경우). POSIX이지만 2001 년부터.

Clock ()는 종종 꽤 유쾌한 해상도를 가지고 있습니다. 밀리 초 레벨에서 시간을 측정하려면 한 가지 대안은 Clock_GetTime ()을 사용하는 것입니다. 이 질문에서 설명했습니다.

(Linux에서 -lrt와 연결해야한다는 것을 기억하십시오).

C ++ 11 및 std::chrono::high_resolution_clock 당신은 이것을 할 수 있습니다 :

#include <iostream>
#include <chrono>
#include <thread>
typedef std::chrono::high_resolution_clock Clock;

int main()
{
    std::chrono::milliseconds three_milliseconds{3};

    auto t1 = Clock::now();
    std::this_thread::sleep_for(three_milliseconds);
    auto t2 = Clock::now();

    std::cout << "Delta t2-t1: " 
              << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count()
              << " milliseconds" << std::endl;
}

산출:

Delta t2-t1: 3 milliseconds

데모 링크 : http://cpp.sh/2zdtu

Clock ()는 Linux에서 밀리 초 또는 초를 반환하지 않습니다. 일반적으로 Clock ()는 Linux 시스템에서 마이크로 초를 반환합니다. Clock ()에 의해 반환 된 값을 해석하는 올바른 방법은 Clocks_per_Sec으로 나누어 얼마나 많은 시간이 지났는지 알아내는 것입니다.

이것은 작동해야합니다 ... Mac에서 테스트되었습니다 ...

#include <stdio.h>
#include <sys/time.h>

int main() {
        struct timeval tv;
        struct timezone tz;
        struct tm *tm;
        gettimeofday(&tv,&tz);
        tm=localtime(&tv.tv_sec);
        printf("StartTime: %d:%02d:%02d %d \n", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec);
}

예 ... 두 번 실행하고 빼요 ...

POSIX 표준에서 clock Clocks_Per_SEC 기호로 정의 된 반환 값이 있으며 구현은 편리한 방식으로이를 자유롭게 정의 할 수 있습니다. Linux 아래에서 나는 행운을 빕니다 times() 기능.

gettimeofday- 문제는 하드웨어 시계를 변경하면 (예 : NTP 포함) 부스트를 변경하면 값이 낮을 수 있다는 것입니다. 얼마 후 음수를 반환합니다.

나는 내 자신의 수업을 만들고 각각 10 마일마다 업데이트하는 것을 선호하므로이 방법은 더 유연하며 가입자를 갖도록 개선 할 수도 있습니다.

class MyAlarm {
static int64_t tiempo;
static bool running;
public:
static int64_t getTime() {return tiempo;};
static void callback( int sig){
    if(running){
        tiempo+=10L;
    }
}
static void run(){ running = true;}
};

int64_t MyAlarm::tiempo = 0L;
bool MyAlarm::running = false;

새로 고침을 위해 SetItimer를 사용합니다.

int main(){
struct sigaction sa; 
struct itimerval timer; 

MyAlarm::run();
memset (&sa, 0, sizeof (sa)); 
sa.sa_handler = &MyAlarm::callback; 

sigaction (SIGALRM, &sa, NULL); 


timer.it_value.tv_sec = 0; 
timer.it_value.tv_usec = 10000; 



timer.it_interval.tv_sec = 0; 
timer.it_interval.tv_usec = 10000; 


setitimer (ITIMER_REAL, &timer, NULL); 
.....

setitimer와 itimer_virtual 및 itimer_real을보십시오.

알람 또는 UALARM 기능을 사용하지 마십시오. 프로세스가 열심히 일할 때 정밀도가 낮습니다.

나는 선호한다 타이머 라이브러리 부스트 단순화를 위해서는 3 분의 1 오리 라이브러리를 사용하고 싶지 않다면 Clock ()를 사용하는 것이 합리적입니다.

업데이트로 Windows Clock ()에서 벽 시계 시간을 측정하는 것으로 보입니다 (Clocks_Per_Sec 정밀도)

 http://msdn.microsoft.com/en-us/library/4e2ess30(VS.71).aspx

Linux에서는 현재 프로세스에서 사용하는 코어에서 CPU 시간을 측정합니다.

http://www.manpagez.com/man/3/clock

그리고 (원래 포스터에서 언급 한 것처럼) 실제로 더 적은 clocks_per_sec보다 정밀도이지만 아마도 Linux의 특정 버전에 달려있을 수 있습니다.

나는 gettimeofday ()를 사용하지 않는 Hola 대두 방법을 좋아합니다. 실행중인 서버에서 관리자가 시간대를 변경했습니다. 시계는 동일한 (올바른) 로컬 값을 표시하도록 업데이트되었습니다. 이로 인해 함수 시간 () 및 gettimeofday ()가 2 시간을 이동했으며 일부 서비스의 모든 타임 스탬프가 멈췄습니다.

나는 a C++ 사용 수업 timeb.

#include <sys/timeb.h>
class msTimer 
{
public:
    msTimer();
    void restart();
    float elapsedMs();
private:
    timeb t_start;
};

회원 기능 :

msTimer::msTimer() 
{ 
    restart(); 
}

void msTimer::restart() 
{ 
    ftime(&t_start); 
}

float msTimer::elapsedMs() 
{
    timeb t_now;
    ftime(&t_now);
    return (float)(t_now.time - t_start.time) * 1000.0f +
           (float)(t_now.millitm - t_start.millitm);
}

사용의 예 :

#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char** argv) 
{
    msTimer t;
    for (int i = 0; i < 5000000; i++)
        ;
    std::cout << t.elapsedMs() << endl;
    return 0;
}

내 컴퓨터의 출력은 '19'입니다. 정확도 msTimer 클래스는 밀리 초의 순서입니다. 위의 사용 예에서 for-루프가 추적됩니다. 이번에는 운영 체제가 main() 멀티 태스킹으로 인해.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top