لا يبدو أن C ++ الحصول على وقت مللي ثانية على مدار الساعة لينكس () يعمل بشكل صحيح

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

  •  09-09-2019
  •  | 
  •  

سؤال

على ويندوز، clock() إرجاع الوقت في مللي ثانية، ولكن في صندوق Linux الخاص بنظام Linux أعمل، فإنه يستقر إلى أقرب 1000 لذلك الدقة هو فقط المستوى "الثاني" وليس إلى مستوى المللي ثانية.

لقد وجدت حلا مع QT باستخدام QTime فئة، مثيل كائن واستدعاء start() على ذلك ثم الدعوة elapsed() للحصول على عدد مللي ثانية المنقضي.

حصلت على نوع من الحظ لأنني أعمل مع QT لتبدأ، لكنني أود الحل الذي لا يعتمد على مكتبات الطرف الثالث،

هل هناك طريقة قياسية للقيام بذلك؟

تحديث

من فضلك لا توصي بزيادة ..

إذا تم التعزيز و 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 ثوان بالضرورة، ولكن يمكن أن أكثر (يمكن لبرنامجك تشغيل خيوط متعددة، وبالتالي يمكن أن تستهلك المزيد من وحدة المعالجة المركزية من الوقت الحقيقي) أو أقل. يقيس تقريب وحدة المعالجة المركزية الوقت تستخدم. لمعرفة الفرق النظر في هذا الرمز

#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

لأن كل ما فعلناه كان نائما ولا يستخدم أي وقت لوحدة المعالجة المركزية! ومع ذلك، باستخدام 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

إذا كنت بحاجة إلى مزيد من الدقة ولكن تريد الحصول عليها وحدة المعالجة المركزية الوقت, ، ثم يمكنك التفكير في استخدام getrusage وظيفة.

أوصي أيضا بالأدوات المقدمة من BOOST. إما أن يعزز الموقت المذكور، أو اختراق شيء خارج Bost.dateTime أو هناك مكتبة جديدة مقترحة في Sandbox - 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 مرات.
    • run_timer, ، التقارير مريحة من | process_timer | النتائج.
  • التحصيم العقلاني المكتبة القياسي C ++ 0x.

هنا هو المصدر قائمة الميزات

لقد كتبت أ 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 ()، والذي سيمنحك الوقت في nanoseconds. (إذا كان المعالج يدعم هذا القرار). انها posix، ولكن من 2001.

الساعة () لديها في كثير من الأحيان حل رديء جدا. إذا كنت ترغب في قياس الوقت في المستوى المليهي، فإن بديل واحد هو استخدام Clock_Gettime ()، كما وأوضح في هذا السؤال.

(تذكر أنك تحتاج إلى الارتباط مع -LRT على Linux).

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

على مدار الساعة () لا ترجع مللي ثانية أو ثواني على لينكس. عادة الساعة () إرجاع microseconds على نظام لينكس. الطريقة الصحيحة لتفسير القيمة التي تم إرجاعها عن طريق الساعة () هي تقسيمها بواسطة 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);
}

نعم ... تشغيله مرتين وطرح ...

في معيار بوسيكس clock لديه قيمة الإرجاع المحددة من حيث Clocks_per_sec رمز وتنفيذ مجاني لتحديد هذا بأي موضة مريحة. تحت لينكس، كان لدي حظ سعيد مع times() وظيفة.

GetTimeOfday - المشكلة هي أن ستكون يمكن أن يكون لها قيم أقل إذا قمت بتغيير ساعة الأجهزة الخاصة بك (مع NTP على سبيل المثال) دفعة - غير متوفرة على مدار الساعة المشروع () - عادة ما تعرج عدد صحيح 4 بايت، يعني Wich أن سعة منخفضة، و بعد بعض الوقت إرجاع الأرقام السالبة.

أفضل إنشاء صفي الخاص وتحديث كل 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، سيكون لديك دقة منخفضة عندما تحصل عملية عملك على عمل شاق.

لكنني أفضل زيادة مكتبة الموقت بالنسبة لبسايتها، ولكن إذا كنت لا ترغب في استخدام مكتبات البارتي الثالثة، فإن استخدام الساعة () تبدو معقولة.

كحدث، يظهر ذلك على مدار الساعة في Windows () يقيس وقت ساعة الحائط (مع الدقة Clocks_per_sec)

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

بينما في Linux يقيس وقت وحدة المعالجة المركزية عبر النوى المستخدمة من قبل العملية الحالية

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

و (يبدو وكأنه لاحظ من الملصق الأصلي) في الواقع مع أقل الدقة من clocks_per_sec، رغم أنه ربما هذا يعتمد على الإصدار المحدد من Linux.

أنا أحب طريقة هولا الصويا لعدم استخدام gettimeofday (). لقد حدث لي على خادم قيد التشغيل غير المسؤول timezone. تم تحديث الساعة لإظهار نفس القيمة المحلية (الصحيحة). تسبب هذا في وقت الوظيفة () و GetTimeOfday () للتحول إلى ساعتين وجميع الطوابع الزمنية في بعض الخدمات عالقة.

كتبت أ 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 فئة من ترتيب milliseconds. في مثال الاستخدام أعلاه، إجمالي الوقت للتنفيذ الذي تناوله forيتم تعقبها. تضمنت هذه المرة نظام التشغيل التبديل داخل وخارج سياق تنفيذ main() بسبب تعدد المهام.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top