2016-04-14 27 views
3

Bazı olaylardan sonra 20 milisaniye (RTP paketleri göndermek için) bazı işlevleri doğru bir şekilde çalıştırmam gerekiyor. olarak20 millisec için doğru bekleyin

std::this_thread::sleep_for(std::chrono::milliseconds(20)); 
boost::this_thread::sleep_for(std::chrono::milliseconds(20)); 
Sleep(20); 

Ayrıca farklı çarpıklıkları:

auto a= GetTickCount(); 
while ((GetTickCount() - a) < 20) continue; 

Ayrıca denenmiş mikro ve nanosaniye sonraki varyantları çalıştılar.
Bu yöntemlerin tümü -6ms ile +12ms arasında bir hata içeriyor ancak kabul edilemez. Nasıl doğru çalışır?

Benim düşüncem, bu + -1ms kabul edilebilir, ancak daha fazla değil. UPDATE1

: süreyi ölçmek için ben çünkü işletim sistemi çekirdekleri zaman ve konuları yönetmek nasıl, std::chrono::high_resolution_clock::now();

+0

Bunu yapmak için bir iş parçacığı ve bir zamanlayıcı kullanıyor musunuz? – ChrisF

+0

Beklenen sürenin doğru olduğunu ölçmenin zamanlayıcılı olduğundan emin misiniz? – MikeCAT

+0

İşletim sistemi nedir? – antiHUMAN

cevap

1

std::chrono::steady_clock kullanarak, basitçe, bu yüzden bu pencereler 7.

üzerinde 0,1 ms doğruluğu hakkında var En azından söyledim. Hepimiz bu tür bir bekleyişin "çirkin" olduğunu ve kaçınılmasının gerektiğini biliyoruz, ama yine de hileyi iyi bir şekilde yapabilecek bir hack.

Sen bazı sistemleri için daha iyi doğruluk verebilir high_resolution_clock, kullanabilirsiniz, ancak işletim sistemi tarafından ayarlanması garanti değildir ve bunu istemiyoruz. steady_clock'un ayarlanmaması garanti edilir ve çoğu zaman high_resolution_clock ile aynı doğruluktadır.

Çok doğru olan "sleep()" işlevleri için bilmiyorum. Belki başka biri bunun hakkında daha fazla şey bilir.

+0

Bu this_thread :: sleep_for (std :: chrono :: milisaniye (n)) veya başka bir şey mi kullanıyorsunuz? – Dmitry

+0

Hayır, uyumak için kullanmıyordum, ancak bazı kodların yürütme hızını ölçmek için. Bunun anlamı, eğer bunu kullanırsan ihtiyacın olan doğruluğa sahip olman. Doğruluk "uyur" söz konusu olduğunda, bilmiyorum, ama önlenebilir, değil mi? İkinci versiyonunuz size ihtiyacınız olan doğruluğu verecektir. – antiHUMAN

3

kısaca kullanmak geçti, çok daha iyi olduğunu yöntemle doğruluğunu alamayacak. Ayrıca, statik bir aralıkta tek başına uyumaya güvenemezsiniz ya da akışınız istenilen gönderim saati oranını hızlıca azaltacaktır, çünkü iş parçacığı kesintiye uğrayabilir veya uyku saatinizden sonra tekrar programlanabilir. Her iterasyonda ne kadar uyumak gerektiğini (yani, 0ms ve 20ms arasında bir yerde) bilmek için sistem saatini kontrol etmelisiniz. Çok fazla ayrıntıya girmeden, bu da RTP akışlarında bir jitter tamponu var ... paket alımındaki varyasyonları hesaba katmak (ağ titreşiminden dolayı veya jitter göndererek). Bu nedenle, muhtemelen +/- 1ms seviye hassasiyetine ihtiyacınız olmayacak.

1

C de, zaman içinde bir nano-uyku fonksiyonu var.

Nanosleep() işlevi, geçerli iş parçacığının, ya rqtp argümanı tarafından belirtilen zaman aralığı ya da çağrı iş parçacığına bir sinyal iletilene kadar eyleminin askıya alınmasına neden olur ve eylemi, bir sinyal yakalama işlevini çağırmaktır veya süreci sonlandırmak için.

Aşağıdaki program 20 mili saniye süreyle uyur.

auto a = std::chrono::steady_clock::now(); 
while ((std::chrono::steady_clock::now() - a) < WAIT_TIME) continue; 

Bu doğru olarak, 0,1 ms hakkında ("bekleme" vermelidir:

int main() 
{ 
    struct timespec tim, tim2; 
    tim.tv_sec = 0; 
    tim.tv_nsec =20000000;//20 milliseconds converted to nano seconds 

    if(nanosleep(&tim , NULL) < 0) 
    { 
     printf("Nano sleep system call failed \n"); 
     return -1; 
    } 

    printf("Nano sleep successfull \n"); 
return 0; 
} 
+2

Bu ne için bir platform? – Dmitry

+1

Bu kod soruyu yanıtlayabilirken, neden ve/veya sorunun nasıl yanıtlandığıyla ilgili ek bağlam sağlayarak uzun vadeli değerini önemli ölçüde artıracaktır. Lütfen bazı açıklama eklemek için cevabınızı [düzenleyin]. – CodeMouse92