0

我有一个运行 while(1) 循环的线程。在那个循环中,我不断检查时间,因为我需要在某些时间执行某些任务。但是,当我将时间打印到屏幕上时,我会看到几秒钟内出现一个几乎 700 毫秒的“空洞”。我尝试设置进程优先级:

 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;

有任何想法吗?

谢谢!

4

2 回答 2

1

首先,最好使用 Cron 进行作业调度,而不是手动等待循环中的必要时刻然后手动启动作业。

根据“时间漏洞”:正如jdv-Jan de Vaan在评论中所说,Linux 不是实时操作系统(以及 Windows 和大多数其他面向消费者的操作系统)。鉴于此,您永远无法确定您的线程将在预期的时间片内以毫秒精度处于活动状态。操作系统调度程序、系统活动,甚至 CPU 节流/节能都可能导致您的应用程序睡眠时间超过一包毫秒。因此,最好考虑一些阈值间隔,而不是固定时间。

于 2013-09-11T12:15:48.877 回答
0

好吧,这可能是调度程序延迟问题,但另一方面,在现代计算机上 700 毫秒是一个非常长的时间,除非计算机真的超载或功率不足,否则我不希望有这么多的调度程序延迟。

另一种可能性是,您用来打印当前时间的逻辑中没有时间间隔,而是错误。我建议您让您的程序将时间空间值转换为自纪元以来的微秒,然后让它以该格式打印出经过的时间。这样你就可以避免日历日期的变幻莫测。像这样的东西:

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/电源使用率。

于 2013-09-11T15:13:19.180 回答