11
votes

Comment faire un dormeur / bloc de fil pour les nanosecondes (ou au moins des millisecondes)?

Comment puis-je bloquer mon fil (peut-être processus) pour les nanosecondes ou peut-être pour une période de millisecondes (au moins)?

Veuillez noter que je ne peux pas utiliser le sommeil, car l'argument à dormir est toujours en quelques secondes.


6 commentaires

Pourriez-vous expliquer pourquoi vous avez besoin d'une telle attente à grain fin?


Un moyen de mettre en œuvre une minuterie définie par l'utilisateur.


Voir la question de la pile sur le débordement Fonction de minuterie pour fournir du temps en nano secondes à l'aide de C ++ .


"Nanosecondes ou peut être des millisecondes" Nano / Milli = 1 / 1.000.000 - Vous devez être certain lequel vous voulez. Une nanoseconde est d'environ 2-3 cycles CPU (en supposant 2-3 GHz), donc environ une ou deux instructions de la machine.


Eh bien, le simple appel à et revenir de votre fonction de minuterie prendra partout de deux douzaines à 500 nanosecondes (au cas où il y a un cache et / ou une Miss TLB). Dans la mesure où, plus fin n'est pas nécessairement meilleur, car Finer ne signifie pas plus précis. Les fonctions d'attente / délai d'attente offertes par le système d'exploitation (voir la réponse par ...) sont aussi bonnes que possible raisonnablement obtenir. Quelque chose de plus fin que ça est idiot.


Duplicaté possible de Fonction de minuterie pour fournir du temps dans nano secondes en utilisant c ++ .


7 Réponses :


3
votes

Essayez USLEeP () . Oui, cela ne vous donnerait pas de la précision nanoseconde, mais les microsecondes vont travailler => Milisecondes aussi.


3 commentaires

Quelque chose à bloquer pour les nanosecondes? Supposons que l'utilisateur donne la période d'attente pour: 2.0000045 , cela échouerait.


Même si un système UNIX ou une autre personne supporte les non-reconstances, il est limité par la vitesse de la CPU. Voyons pourquoi. Considérez le processeur de 2,5 GHz. Dans une seconde, il peut faire environ 10 ^ 8 Commandes de processeur Cela signifie que environ 100 opérations par microseconde => Il est possible de gérer cette granulité sur ce processeur, mais 0,1 opération par nanoseconde => Même s'il y avait du soutien de cette granulité, le processeur peut " t Mesurer le temps correctement.


USLEEP a été obsolète dans POSIX 2003 et supprimé en 2008.



2
votes

La résolution nano-seconde précise sera impossible sur un système d'exploitation Général Linux, en raison du fait que des distributions généralement linux ne sont pas des systèmes d'exploitation en temps réel (dur). Si vous VRAIMENT BESOIN DE CETTE CONTRÔLE DE GRAINE FINÉE DU TIMAGE, envisagez d'utiliser un tel système d'exploitation.

Wikipedia a une liste de certains systèmes d'exploitation en temps réel ici: http://en.wikipedia.org / wiki / rtos (Notez que cela ne dit pas si elles sont douces ou difficiles en temps réel, vous devrez donc faire des recherches).


1 commentaires

Nous n'utilisons pas le service commercial Linux O / S Avalable sur le marché. Nous utilisons notre propre distribution.



3
votes

Utilisation de toute variante de sommeil pour Pthreads, le comportement n'est pas garanti. Tous les fils peuvent également dormir car le noyau n'est pas au courant des différents threads. Par conséquent, une solution est requise que la bibliothèque Pthread peut gérer plutôt que le noyau.

Une solution plus sûre et plus propre à utiliser est le pthread_cond_timédiawait ... xxx

pour pthread_cond_timpedwait, Vous devez spécifier combien de temps à attendre de l'heure actuelle.

Maintenant par l'utilisation de la fonction myWait () Seul le fil appelant qu'il va dormir et non les autres Pthreads. >


4 commentaires

Le noyau est très conscient des threads, du point de vue du noyau, ce sont des processus distincts qui partagent la mémoire et un autre État.


Cette réponse a une information erronée. SLEEP et ses variantes sont destinées au fil d'appel, pas pour le processus. Cependant, l'idée d'utiliser pthread_cond_wait plutôt qu'une fonction de sommeil peut être très bonne, surtout si la raison du petit sommeil est de sonder certaines conditions.


@Douglas: Le noyau n'est pas au courant des threads de niveau utilisateur, si je ne me trompe pas. C'est pourquoi, lorsqu'un thread de niveau utilisateur fait un appel de système de blocage, tous les threads de niveau utilisateur sont bloqués. Mais la même chose n'est pas applicable pour les threads du noyau.


@ kingmasher1: Vous avez raison. Le noyau a des connaissances uniquement sur les fils du noyau. Il n'a pas d'informations sur les threads au niveau de l'utilisateur et donc le problème.



3
votes

nanosleep vous permet de spécifier la précision du Dors à nano-secondes. Cependant, la résolution effective de votre sommeil est susceptible d'être beaucoup plus grande en raison des limitations du noyau / de la CPU.


1 commentaires

Sur une machine haut de gamme, il peut vraiment dormir avec une résolution sous-microseconde (pas beaucoup plus petite, probablement 500-900 NS est le sommeil le plus court que vous atteindrez).



6
votes

Un moyen relativement portable est d'utiliser Sélectionner () code> ou pSélection () code> sans descripteurs de fichier:

void sleep(unsigned long nsec) {
    struct timespec delay = { nsec / 1000000000, nsec % 1000000000 };
    pselect(0, NULL, NULL, NULL, &delay, NULL);
}


5 commentaires

Tout système avec pSélection aura presque certainement nanosleep . Ils ont été tous deux inventés par Posix et les deux ajoutés en même temps, je pense.


C'est un bon, mais notre CE-Linux prend en charge Nanosleep, cependant, pour la clarté et les futures implémentations, votre code est utile. Merci.


Cela ne compile pas tel quel.


@Lotolo a ajouté struct , n'a pas remarqué qu'il avait c balise.


Vous pouvez également ajouter ppoll () qui est arrivé long pSélection () (et nanosleep () je suppose).



12
votes

nanosleep ou clock_nanosleep est la fonction que vous devriez utiliser (ce dernier vous permet de spécifier du temps absolu plutôt que de l'heure relative, et utilisez plutôt l'horloge monotone ou d'autres horloges plutôt. que simplement l'horloge en temps réel, qui pourrait courir à l'envers si un opérateur le réinitialise).

Soyez au courant de ce que vous obtiendrez rarement mieux que plusieurs microsecondes en termes de résolution, et il arrondit toujours la durée du sommeil, plutôt que d'arrondir. (Il serait généralement impossible de toute façon, dans la plupart des machines, la saisie et la sortie de Kernelspace prend plus qu'un microseconde.)

Également, si possible, je suggérerais d'utiliser un appel qui bloque en attente d'un événement plutôt que de dormir pour des intervalles minuscules puis de voter. Par exemple, pthread_cond_wait , pthread_cond_timédiawait , sem_wait , SEM_TIMEDWAIT , Sélectionnez , Lire , etc. En fonction de la tâche effectuée votre fil et comment elle se synchronise avec d'autres threads et / ou communique avec le monde extérieur.


3 commentaires

Notez que pour la mise en œuvre d'une minuterie, vous voulez probablement clock_nanosleep avec heure absolue (le temps d'expiration de la minuterie suivant précomptes). Avec une heure relative, sauf si vous prenez des précautions supplémentaires pour régler vos intervalles de sommeil en fonction du temps mesuré, vous accumulerez une erreur.


Il est intéressant de noter que la résolution de l'horloge est indiquée à 1E-9 sur mon ordinateur, même s'il est juste de près impossible à attendre une nano-seconde avec une architecture existante.


@Alexiswilke: Cela ne signifie pas que vous pouvez attendre une nanoseconde, que le temps rapporté a une signification à une nanoseconde.



1
votes

sur un système embarqué avec accès à plusieurs minuteries matérielles, créez une horloge à grande vitesse pour votre nanoseconde ou votre microseconde attend. Créez une macro pour l'activer et la désactiver et gérer votre traitement haute résolution dans la routine de service d'interruption de la minuterie.

Si vous gaspillez la puissance et l'attente d'attente n'est pas un problème, effectuez des instructions de non-op - mais vérifiez que le compilateur n'oblise pas vos non-UPS. Essayez d'utiliser des types volatils.


1 commentaires

Les boucles de retard ne sont pas utilisables sur les processeurs modernes hautes performances (y compris les téléphones) pour autre chose que "attendre au moins quelques dizaines de nanosecondes", mais éventuellement 5x à 10 fois en fonction de la fréquence de la CPU Idle vs. Max Turbo. De plus, les NOPS ne contribuent pas de manière linéaire à retarder, sauf en boucle si vous les utilisez suffisamment d'un goulot d'étranglement sur le front-end au lieu de la branche d'arrière 1 prise par horloge. Voir aussi Comment calculer l'heure pour une boucle de délai d'ASM sur X86 Linux? pour une boucle Spin-Attente RDTSC.