2010-06-18 8 views
20

Je suis récemment tombé sur le besoin de dormir le fil actuel pour une période de temps exacte. Je connais deux méthodes pour le faire sur une plate-forme POSIX: en utilisant nanosleep() ou en utilisant boost::this_thread::sleep(). Par curiosité plus que toute autre chose, je me demandais quelles étaient les différences entre les deux approches. Y a-t-il une différence de précision, et y a-t-il une raison quelconque pour utiliser l'approche Boost?boost :: this_thread :: sleep() contre nanosleep()?

nanosleep() approche:

#include <time.h> 
... 
struct timespec sleepTime; 
struct timespec returnTime; 
sleepTime.tv_sec = 0; 
sleepTime.tv_nsec = 1000; 
nanosleep(&sleepTime, &returnTime); 

approche Boost:

#include <boost/date_time/posix_time/posix_time.hpp> 
#include <boost/thread/thread.hpp> 
... 
boost::this_thread::sleep(boost::posix_time::nanoseconds(1000)); 
+3

Juste une petite note à l'exemple: 'nanoseconds' n'est pas disponible sur tous les systèmes. L'utilisation de 'microseconds' serait plus sûre. – real4x

Répondre

26

Les quelques raisons pour lesquelles stimuler l'utilisation que je peux penser à:

  • boost::this_thread::sleep() est un point d'interruption dans boost.thread
  • boost::this_thread::sleep() peut être goutte dans remplacé par C++ 0x de std::this_thread::sleep_until() dans future

Pour pourquoi pas - si vous n'utilisez pas de threads du tout, ou de tout le reste en vous Le projet utilise des appels POSIX, alors nanosleep() a plus de sens. En ce qui concerne la précision, sur mon système, boost et nanosleep() appellent le même appel système hrtimer_nanosleep(). J'imagine que les auteurs de boost essayent d'obtenir la plus haute précision possible sur chaque système et pour moi, il arrive à être la même chose que ce que fournit nanosleep().

+6

+1 - il convient de noter que la synchronisation basée sur les threads dort - même nanosleep - n'est pas fiable au mieux. –

+0

Une raison d'utiliser 'this_thread :: sleep()' est que cela prend du temps dans les unités que vous aimez: 'sleep (seconds (10))', 'sleep (nanosecondes (10))', 'sleep (attoseconds (10)) ». La résolution matérielle ne change pas, mais quelle que soit la résolution proposée, elle peut être exposée sans avoir besoin d'introduire de nouvelles API de sommeil ('sleep',' usleep', 'nanosleep', etc.). – bames53

4

est-il une raison de ne pas utiliser l'approche Boost

Je suppose que cela est assez évident, mais la seule raison que je peux penser est que vous auriez besoin d'un coup de pouce t o compilez votre projet.

+0

Je suppose que j'aurais dû dire que le projet utilise déjà d'autres bibliothèques boost. Néanmoins, une réponse valable à la question générale. –

5

Que diriez-vous parce que votre exemple nanonsleep est faux.

#include <time.h> 
... 
struct timespec sleepTime; 
struct timespec time_left_to_sleep; 
sleepTime.tv_sec = 0; 
sleepTime.tv_nsec = 1000; 
while((sleepTime.tv_sec + sleepTime.tv_nsec) > 0) 
{ 
    nanosleep(&sleepTime, &time_left_to_sleep); 
    sleepTime.tv_sec = time_left_to_sleep.tv_sec; 
    sleepTime.tv_nsec = time_left_to_sleep.tv_nsec; 
} 

Il est vrai que si vous ne dormez pour 1 microseconde se réveiller trop tôt ne devrait pas être un problème, mais dans le cas général, c'est la seule façon de le faire.

Et juste pour faire glacer le gâteau en faveur de boost, boost::this_thread::sleep() est mis en œuvre en utilisant nanosleep(). Ils ont juste pris soin de tous les cas de coin fous pour vous.

+0

+1, j'ai pensé que boost 'sleep()' serait implémenté avec 'nanosleep()', bon pour avoir confirmation. –

+0

Où voyez-vous le sommeil mis en œuvre avec nanosleep? Dans thread.hpp je vois: inline void sleep (xtime const et abs_time) {sleep (system_time (abs_time)); } – clemahieu

+0

@clemahieu: Ce n'est pas un appel à ':: sleep' (sinon vous seriez limité à une résolution en secondes). C'est un appel à l'une des nombreuses autres surcharges 'boost :: this_thread :: sleep', dont vous pouvez trouver la définition dans' libs/thread/src/pthread/thread.cpp'. –

2

Pour moi, la principale raison de l'utilisation de la variante boost est l'indépendance de la plate-forme. Si vous devez compiler votre application pour les plates-formes posix et Windows, par exemple, la mise en veille de la plate-forme n'est pas suffisante.