J'ai besoin d'une minuterie pour exécuter des rappels avec une résolution relativement faible. Quelle est la meilleure façon d'implémenter une telle classe de minuteur C++ sous Linux? Y a-t-il des bibliothèques que je pourrais utiliser?classe de minuterie dans linux
Répondre
Si vous écrivez dans un cadre (Glib, Qt, Wx, ...), vous aurez déjà une boucle d'événement avec des fonctionnalités de rappel chronométré. Je suppose que ce n'est pas le cas.
Si vous écrivez votre propre boucle d'événement, vous pouvez utiliser le gettimeofday
/select
paire (struct timeval
, précision microseconde) ou la clock_gettime
/nanosleep
paire (struct timespec
, précision nanoseconde) pour votre propre diffuseur d'événements. Même si cette dernière est à plus haute résolution, l'ordonnancement n'est jamais aussi précis, alors prenez tout ce qui vous convient le mieux.
#include <algorithm>
#include <functional>
#include <vector>
#include <errno.h>
#include <sys/time.h>
#include <unistd.h>
using namespace std;
class scheduler {
public:
scheduler();
int events();
void addEvent(const struct timeval, int (*)(void *), void *);
int dispatchUntil(const struct timeval &);
bool waitUntil(const struct timeval * = NULL);
int loopUntil(const struct timeval * = NULL);
private:
static bool tv_le(const struct timeval &, const struct timeval &);
struct event {
struct timeval when;
int (*callback)(void *);
void *data;
};
static struct _cmp
: public binary_function<bool, const struct event &, const struct event &>
{
bool operator()(const struct event &a, const struct event &b) {
return !tv_le(a.when, b.when);
}
} cmp;
vector<struct event> heap;
};
bool scheduler::tv_le(const struct timeval &a, const struct timeval &b) {
return a.tv_sec < b.tv_sec ||
a.tv_sec == b.tv_sec && a.tv_usec <= b.tv_usec;
}
scheduler::scheduler() : heap() {}
int scheduler::events() {
return heap.size();
}
void scheduler::addEvent(const struct timeval when, int (*callback)(void *), void *data) {
struct event ev = {when, callback, data};
heap.push_back(ev);
push_heap(heap.begin(), heap.end(), cmp);
}
int scheduler::dispatchUntil(const struct timeval &tv) {
int count = 0;
while (heap.size() > 0 && tv_le(heap.front().when, tv)) {
struct event ev = heap.front();
pop_heap(heap.begin(), heap.end(), cmp);
heap.pop_back();
ev.callback(ev.data);
count++;
}
return count;
}
bool scheduler::waitUntil(const struct timeval *tv) {
if (heap.size() > 0 && (!tv || tv_le(heap.front().when, *tv)))
tv = &heap.front().when;
if (!tv)
return false;
struct timeval tv2;
do {
gettimeofday(&tv2, NULL);
if (tv_le(*tv, tv2))
break;
tv2.tv_sec -= tv->tv_sec;
if ((tv2.tv_usec -= tv->tv_usec) < 0) {
tv2.tv_sec--;
tv2.tv_usec += 1000000;
}
} while (select(0, NULL, NULL, NULL, &tv2) < 0 && errno == EINTR);
return heap.size() > 0 && tv_le(*tv, heap.front().when);
}
int scheduler::loopUntil(const struct timeval *tv) {
int counter = 0;
while (waitUntil(tv))
counter += dispatchUntil(heap.front().when);
return counter;
}
Avertissement: J'aime C. Je n'écris jamais en C++. Je fais juste semblant de connaître la langue.
Avertissement: écrit tout à l'heure et totalement non testé. L'idée de base est de garder les événements dans une file d'attente prioritaire, d'attendre le premier, de l'exécuter et de répéter.
+1 pour le prétendant C++ – jacknad
Essayez la fonction clock_gettime(), défini dans time.h:
int clock_gettime(clockid_t clk_id, struct timespec *tp);
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
En général, vous pourrait l'appeler comme ceci:
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
Désolé, mais je voulais dire une minuterie où l'on peut enregistrer les rappels à lancer après un intervalle spécifié. – jackhab
Utilisez le boost :: asio bibliothèque. Il a deux temporisateurs synchrones et asynchrones qui appellent un rappel.
http://www.boost.org/doc/libs/1_37_0/doc/html/boost_asio/tutorial.html
Le struct timeval de l'en-tête de time.h est ce que vous recherchez. Il a le temps en secondes et en nanosecondes. Donc le temps total en nanosecondes est timeval.tv_sec * 1000000 + timeval.tv_usec. Assez facile, je pense.
#include <time.h>
timeval theStartTime;
gettimeofday(&theStartTime);
std::cout<<"The time we got's seconds field = "<<theStartTime.tv_sec<<std::endl;
std::cout<<"The time we got's nanoseconds field = "<<theStartTime.tv_usec<<std::endl;
Désolé, mais je voulais dire une minuterie où l'on peut enregistrer les rappels à lancer après un intervalle spécifié. – jackhab
Voici un lien pour une classe de minuterie. Vous n'aurez besoin que de créer la minuterie et de la transmettre pour le rechargement automatique ou non. un pointeur sur la fonction de rappel. et soit si vous voulez qu'il soit géré par un fil ou avec un signal. Si vous choisissez le signal, vous devez également passer le signo.
http://timerlinux.codeplex.com/
Si tu veux étudier plus sur minuterie ou signaux il y a un bon livre appelé programmation système Linux. Vous n'aurez qu'à lire 3 chapitres et expliquer tout cela.
- 1. Intervalles de minuterie, Faire une minuterie arrêter une autre minuterie -
- 2. contrôle de minuterie dans vb.net
- 3. Comment activer une minuterie à partir d'un autre fil/classe
- 4. Travaux de minuterie Sharepoint
- 5. Comment accéder à une minuterie d'une autre classe en C#
- 6. Minuterie de réinitialisation
- 7. Algorithme de minuterie efficace
- 8. Problème d'interruption de minuterie dans vb.net
- 9. Enregistrement d'événements écoulés par minuterie
- 10. Sélecteur de minuterie pour iPhone
- 11. Minuterie fiable dans une application console
- 12. Comment régler une minuterie dans asp.net
- 13. Minuterie en Python
- 14. Android TextView Minuterie
- 15. Problème lors de l'utilisation de la minuterie
- 16. Comment définir le chemin de classe sous Linux?
- 17. ASP.NET: Minuterie et position de défilement
- 18. graphe de flot sur une minuterie
- 19. Comment réinitialiser une minuterie en C#?
- 20. Comment changer le format de la minuterie
- 21. Modification de classes sur une minuterie Jquery
- 22. Obtenir des ticks de minuterie en Python
- 23. Utilisation d'une minuterie en C#
- 24. Comment régler une minuterie javascript
- 25. Minuterie haute performance vs StopWatch
- 26. Minuterie sur le papier peint Cycler
- 27. Variables statiques locales dans l'événement Timer.Tick (arrêt d'une minuterie)
- 28. Faire défiler des DataTemplates dans ListBox sur une minuterie
- 29. Comment utiliser le filetage en toute sécurité pour une minuterie (Modifier les propriétés de la minuterie de différents fils)
- 30. Meilleure façon de créer une minuterie à l'écran
Qu'est-ce qu'une résolution relativement faible? – Loki
haha, Loki. exactement ce que je pensais quand je lisais sa question –
des centaines de millisecondes à secondes – jackhab