簡體   English   中英

Linux C ++:時間采樣中的“漏洞”

[英]Linux C++: “Holes” in time sampling

我有一個運行while(1)循環的線程。 在那個循環中,我會不斷檢查時間,因為我需要在某些時間執行某些任務。 但是,當我將時間打印到屏幕上時,我發現幾秒鍾后就會出現近700ms的“空洞”。 我嘗試設置prcoess優先級:

 policy =  SCHED_FIFO;
 param.sched_priority = 18; 
 if( sched_setscheduler( id, policy, &param ) == -1 ) 
 {
            printf("Error setting scheduler/priority!\n");
  }

以及線程優先級:

pthread_attr_t attr;
struct sched_param param;
pthread_attr_init(&attr);
pthread_attr_setschedpolicy(&attr, SCHED_RR);
param.sched_priority = 50;
pthread_attr_setschedparam(&attr, &param);
    m_INVThreadID  = pthread_create( &m_BaseStationLocatorsThread, &attr,        
                                     ThreadBaseStationLocatorsHandler, (void*) 
                                                                (this));//Linux

但這沒有幫助。

我得到時間的方式是:

 struct timespec start;


      clock_gettime( CLOCK_MONOTONIC_RAW, &start);
            //gettimeofday(&tim, NULL);
            //wInitTime = tim.tv_sec*1000 + tim.tv_usec/1000.0;
            double x = start.tv_sec;
            double y = start.tv_nsec;
            x=x*1000;
            y = y/1000000;
            double result = x+ y;
            return result;

要么:

STime   TimeHandler::GetTime()
{
    STime tmpt;
    time_t rawtime;
        tm * timeinfo;
        time(&rawtime);
        timeinfo=localtime(&rawtime);   
        tmpt.day_of_month = timeinfo->tm_mday;
        tmpt.month = timeinfo->tm_mon+1;
        tmpt.year = timeinfo->tm_year+1900;
        tmpt.Hours =  timeinfo->tm_hour;
        tmpt.Min = timeinfo->tm_min;
        tmpt.Sec =  timeinfo->tm_sec;
        tmpt.MilliSeconds = GetCurrentTimeMilliSeconds();
        return tmpt;
}

現在使用以下命令打印時間:

STime timeinfo = GetTime();
    string curTime;
    int datePart; 
    string datePartSTR;
    std::ostringstream convert;

    datePart =timeinfo.day_of_month;
    convert << datePart;
    //curTime.append( convert.str());
    convert << "/";
    datePart = timeinfo.month;
    convert << datePart;
    //curTime.append( convert.str());
        convert << "/";
    datePart =timeinfo.year;
    convert << datePart;
    //curTime.append( convert.str());   

        convert << " ";
        datePart =timeinfo.Hours;
            if (timeinfo.Hours<10)
            convert <<0;
    convert << datePart;
    //curTime.append( convert.str());
        convert << ":";
        datePart =timeinfo.Min;
            if (timeinfo.Min<10)
            convert <<0;
    convert << datePart;
    //curTime.append( convert.str());
        convert << ":";
        datePart =timeinfo.Sec;
        if (timeinfo.Sec<10)
            convert <<0;
    convert << datePart;
        convert << ":";
            datePart =timeinfo.MilliSeconds;
        if (timeinfo.MilliSeconds<100)
                convert << 0;
        if (timeinfo.MilliSeconds<10)
                convert << 0;
    convert << datePart;
    curTime.append( convert.str());


        return curTime;

有任何想法嗎?

謝謝!

首先,最好使用Cron進行作業調度,而不是手動等待必要的循環時間然后手動啟動作業。

根據“時間漏洞”:正如jdv-Jan de Vaan在評論中所說,Linux不是實時操作系統(以及Windows和大多數其他面向消費者的操作系統)。 鑒於此,您永遠無法確保線程在預期的時間段內處於活動狀態,且精度為毫秒。 操作系統調度程序,系統活動,甚至CPU節流/節能都可能導致您的應用休眠時間超過一毫秒。 因此,與其固定時間,不如考慮一些閾值間隔。

好吧,這可能是調度程序延遲問題,但是另一方面,現代計算機上700mS的時間太長了,除非計算機真正過載或功率不足,否則我不希望有那么多的調度程序延遲。

另一種可能性是,沒有時間差,而是您用來打印當前時間的邏輯錯誤。 我建議您讓程序將時空值轉換為微秒(自紀元),然后以該格式打印經過的時間。 這樣,您就可以避免日歷日期的變化。 像這樣:

uint64_t GetMicrosecondsSinceEpoch()
{
   struct timespec ts;
   if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) return 0;  // error!
   return (((uint64_t)ts.tv_sec)*1000000) + ((uint64_t)(ts.tv_nsec)/1000)));
}

[...]

static uint64_t prevMicros = 0;
uint64_t nowMicros = GetMicrosecondsSinceEpoch();
int64_t elapsedMicros = nowMicros-prevMicros;
if (prevMicros != 0)
{ 
   printf("Elapsed microseconds since previous time is %lli\n", elapsedMicros);
   if (elapsedMicros >= 500000) printf("ERROR, more than 500mS passed since last time!?\n");
}
prevMicros = nowMicros;

如果以上顯示錯誤,則可能是調度問題; 如果不是,則可能是日期轉換問題。

順便說一句,如果您為每個要喚醒的事件計算微秒-自-紀元值,則只需取所有這些值中的最小值,然后從該最小值中減去GetMicrosecondsSinceEpoch()返回的當前值,然后睡眠那么長的時間...這樣,您只有在(大約)該時間處理下一個事件時才會醒來。 與定期醒來僅再次回到睡眠狀態相比,這將為您提供更好的時間准確性和更少的CPU /功耗使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM