在Linux中获得更精确的时序控制

时间:2016-04-06 12:52:06

标签: c linux timing

我正在尝试为数字电视创建低抖动组播源。有问题的程序应缓冲输入,根据流中的PCR值计算预期时间,然后以相对精确的间隔发送数据包。但是,这不是在RTOS上运行,因此预计会出现一些时序差异。

这是基本代码(相关变量已初始化,我在这里省略了代码):

while (!sendstop) { 
    //snip
    //put 7 MPEG packets in one UDP packet buffer "outpkt"
    //snip
      waittime = //calculate from PCR values - value is in microseconds
    //waittime is in the order of 2000 -> 2ms
              sleeptime=curtime;
              sleeptime.tv_nsec += waittime * 1000L;
                    sleeptime.tv_sec += sleeptime.tv_nsec / 1000000000;
                    sleeptime.tv_nsec %= 1000000000;
              while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &sleeptime, NULL) && errno == EINTR) {
                    printf("I");
              }       
              sendto(sck,outpkt,1316,0,res->ai_addr,res->ai_addrlen);    //send the packet       
              clock_gettime(CLOCK_MONOTONIC,&curtime);                            
}

但是,这会导致发送速度太慢(因为某些处理也需要时间),因此缓冲区会填满。所以,我认为我应该在" sleeptime"之间找到区别。 (应该是的时间)和" curtime" (实际时间)并从未来减去#34;等待时间"。这几乎可以工作,但现在有点太快了,现在我得到一个空的缓冲区。

我的下一个想法是在减去它之前将差值乘以某个值,就像这样(在#34之上;而......"):

difn=curtime.tv_nsec-ostime.tv_nsec;
if (difn<0) difn+=1000000000; 
  sleeptime.tv_nsec = sleeptime.tv_nsec-(difn*difnc)/1000;  //difnc - adjustment
   if (sleeptime.tv_nsec<0) {
        sleeptime.tv_nsec+=1000000000;
        sleeptime.tv_sec--;
   }

然而,不同的difnc值在一天中的不同时间,服务器等工作。需要根据程序的操作进行某种自动调整。我能想到的最好的方法是每当缓冲区满或空时递增/递减它,然而,这会导致'#34;太快&#34; - &#34;太慢&#34;。我试着调整&#34; difnc&#34;值取决于缓冲区的满/空是多少,但这只是导致&#34;慢速&#34; - &#34;快速&#34;周期。

如何正确地自动导出&#34; difnc&#34;值或是否有一些其他方法可以获得更精确的时间,而不仅仅是&#34; clock_nanosleep&#34;功能但没有忙等待(服务器有其他事情要做)?

0 个答案:

没有答案
相关问题