thread et nanosleep( )

thread et nanosleep( ) - C++ - Programmation

Marsh Posté le 28-08-2002 à 16:26:07    

Bonjour :cry:
 
Je voudrais faire ceci
 
exécuter le code du thread_01
 
endormir le thread_01 pendant 1ms
exécuter le code du thread_02 pendant une partie de cette 1ms
 
endormir le thread_02 pendant 1ms
exécuter le code du thread_01 pendant une partie de cette 1ms
 
.....
 
Les fonctions usleep, nanosleep, setitimer ne sont valables que pour les processus (elles endorment le processus entier si on l'utilise dans un thread) et en plus elles ne permettent pas d'obtenir un delai avec un précision inférieure à 10ms :(
 
La seule solution qui me vient, c'est d'installer RT Linux et d'utiliser les fonctions pthread_make_periodic_np et pthread_wait_np :ouch:
 
Le pb c'est que ça va pas être simple du tout :fou:
 
Donc si qq'un connait une fonction comme nanosleep qui puisse
   1)être valable pour les threads et  
    2) avoir une précision inférieure à 10ms

ça me ferais gagner beaucoup de temps
 
C'est surtout la précision <10ms qui m'interresse

Reply

Marsh Posté le 28-08-2002 à 16:26:07   

Reply

Marsh Posté le 28-08-2002 à 16:36:32    

up !
j'suis preneur egalement pour le parametrage inferieur a 10 ms ...

Reply

Marsh Posté le 28-08-2002 à 16:36:45    

Peut-être que si tu n'utilises pas les thread et que tu crées des pipes entre tes applis ce serait une solution pour utiliser nanosleep !
Seul soucis (et de taille) je ne suis pas du tout sûr de moi et je ne connais les pipes que de nom... (si on peu dire)

Reply

Marsh Posté le 28-08-2002 à 16:47:35    

"Peut-être que si tu n'utilises pas les thread et que tu crées des pipes entre tes applis ce serait une solution pour utiliser nanosleep ! "
J'ai pas bien compris, mais de toute façon, même si il n'y a qu'un seul thread, la fonction nanosleep ne marche pas en dessous de 10ms :)
 

Reply

Marsh Posté le 28-08-2002 à 17:43:00    

Oups j'oubliai qu'il ne fonctionnait pas...
En fait, ce que je voulais dire c'est que tu ne t'amuses pas avec des threads mais tu fais à la place de chacun d'eux une application. Les applications dialogues ensuite entre elles via des pipes. C'est comme s'il y avait des connections de type réseau entre chaque appli mis à part qu'elles tournent toutes sur la même machine et qu'elles peuvent avoir directement accès à la bonne zone de mémoire (du moins je crois). Mais là-dedans je ne suis pas trop calé... Un gar m'a dit trois mots là-dessus et alors je lui ai dit : "Mais voyons pourquoi s'embêter puisqu'il existe les threads ?" La réponse était simple : à son époque, pourtant pas si lointaine, les threads n'étaient qu'à leur balbutiement d'où cette technique.... Mais bon je ne lui en ai pas demandé plus car je me suis dit "Heureusement pour moi que les threads existent !"
 
Désolé, mais pour le moment je n'en sais pas plus et je crois que cela risque de durer un peu car je n'ai pas trop de temps en ce moment pour faire de la lecture tranquille le soir :)

Reply

Marsh Posté le 28-08-2002 à 18:07:42    

10couNAS a écrit a écrit :

Bonjour :cry:
Les fonctions usleep, nanosleep, setitimer ne sont valables que pour les processus (elles endorment le processus entier si on l'utilise dans un thread) et en plus elles ne permettent pas d'obtenir un delai avec un précision inférieure à 10ms :(




 
La fonction select fonctionne bien avec les threads.

Code :
  1. int MySleepMs( unsigned int timeout_ms )
  2. {
  3.         struct timeval tv;
  4.         tv.tv_sec = timeout_ms/1000;
  5.         tv.tv_usec = (timeout_ms%1000) * 1000;
  6.         select(0, NULL, NULL, NULL, &tv);
  7.         return 0;
  8. }


 
Pour faire passer la main aux autres threads, tu devrais pouvoir utiliser la fonction pthread_yield. Mais je ne suis pa sûr que ce soit dans toutes les implémentations des threads POSIX.

Reply

Marsh Posté le 28-08-2002 à 20:16:09    

nanosleep marche très bien dans les threads (testé sur Linux et Solaris).
 
Au passage, pour ce que tu fais, ce serait mieux d'utiliser des sémaphores en plus des nanosleep.


---------------
« No question is too silly to ask, but, of course, some are too silly to answer. » -- Perl book
Reply

Marsh Posté le 29-08-2002 à 08:23:42    

Jar Jar, tu arrives à obtenir quoi comme précision avec nanosleep?

Reply

Marsh Posté le 29-08-2002 à 08:56:37    

En ayant programmé un delai de 1ms, voici les résultats :
Duree du nanosleep     => 16,397 ms
Duree du select        =>  7,466 ms
Duree du pselect       =>  9,355 ms
 

Code :
  1. #include <sys/time.h>
  2. #include <sys/types.h>
  3. #include <unistd.h>
  4. #include <stdio.h>
  5. #include <time.h>
  6. int main(void)
  7. {
  8. struct timeval date_debut;
  9. struct timeval date_fin;
  10. struct timespec duree_nanosleep;
  11. struct timeval duree_select;
  12. struct timespec duree_pselect;
  13. duree_nanosleep.tv_sec=0;
  14. duree_nanosleep.tv_nsec=1000000; //1 ms
  15. fprintf(stdout,"NANOSLEEP => Durée = %ld.%09ld",duree_nanosleep.tv_sec,duree_nanosleep.tv_nsec);
  16. puts("" );
  17. gettimeofday(&date_debut,NULL);
  18. nanosleep(&duree_nanosleep,&duree_nanosleep);
  19. gettimeofday(&date_fin,NULL);
  20. fprintf(stdout,"Avant le nanosleep date = %ld.%06ld\n",date_debut.tv_sec,date_debut.tv_usec);
  21. fprintf(stdout,"Après le nanosleep date = %ld.%06ld\n",date_fin.tv_sec,date_fin.tv_usec);
  22. duree_select.tv_sec=0;
  23. duree_select.tv_usec=1000; //1ms
  24. fprintf(stdout,"SELECT ====> Durée = %ld.%06ld",duree_select.tv_sec,duree_select.tv_usec);
  25. puts("" );
  26. gettimeofday(&date_debut,NULL);
  27. select(0,NULL,NULL,NULL,&duree_select);
  28. gettimeofday(&date_fin,NULL);
  29. fprintf(stdout,"Avant le select date = %ld.%06ld\n",date_debut.tv_sec,date_debut.tv_usec);
  30. fprintf(stdout,"Après le select date = %ld.%06ld\n",date_fin.tv_sec,date_fin.tv_usec);
  31. duree_pselect.tv_sec=0;
  32. duree_pselect.tv_nsec=1000000; //1ms
  33. fprintf(stdout,"PSELECT ===> Durée = %ld.%09ld",duree_pselect.tv_sec,duree_pselect.tv_nsec);
  34. puts("" );
  35. gettimeofday(&date_debut,NULL);
  36. pselect(0,NULL,NULL,NULL,&duree_pselect);
  37. gettimeofday(&date_fin,NULL);
  38. fprintf(stdout,"Avant le pselect date = %ld.%06ld\n",date_debut.tv_sec,date_debut.tv_usec);
  39. fprintf(stdout,"Après le pselect date = %ld.%06ld\n",date_fin.tv_sec,date_fin.tv_usec);
  40. }

Reply

Marsh Posté le 29-08-2002 à 11:23:52    

BUGS
       The current implementation of nanosleep is based on the  normal  kernel
       timer  mechanism,  which  has  a  resolution  of  1/HZ s (i.e, 10 ms on
       Linux/i386 and  1 ms  on  Linux/Alpha).   Therefore,  nanosleep  pauses
       always for at least the specified time, however it can take up to 10 ms
       longer than specified until the process becomes runnable again. For the
       same  reason,  the value returned in case of a delivered signal in *rem
       is usually rounded to the next larger multiple of 1/HZ s.
 
       As some applications require much more precise pauses (e.g.,  in  order
       to  control  some time-critical hardware), nanosleep is also capable of
       short high-precision pauses. If the process is scheduled under a  real-
       time policy like SCHED_FIFO or SCHED_RR, then pauses of up to 2 ms will
       be performed as busy waits with microsecond precision.


 
Donc il faut mettre en place une politique de scheduling avec pthread_setscheduler et tu auras la précision requise.


---------------
« No question is too silly to ask, but, of course, some are too silly to answer. » -- Perl book
Reply

Marsh Posté le 29-08-2002 à 11:23:52   

Reply

Marsh Posté le 29-08-2002 à 15:52:05    

Ok Jar Jar et merci
 
Par contre, j'ai rajouté ça dans mon programme

Code :
  1. struct sched_param param;
  2. param.sched_priority=1;
  3. if (sched_setscheduler (getpid(), SCHED_RR, & param) < 0) {
  4. perror ("setscheduler" );
  5. exit (1);
  6. }


 
j'ai compilé gcc -o mon_prog mon_prog.c
tout s'est bien passé
après j'ai fait  
 
>su
>Password ****
#chown root.root mon_prog
#chmod u+s mon_prog
#exit
>./mon_prog
Mon programme s'est lancé et au bout de deux secondes, tout a planté apparemment.
Je ne peux plus rien faire du tout sous mon linux!!

Reply

Marsh Posté le 29-08-2002 à 16:13:26    

Là je suis désolé, je ne peux pas t'aider, je n'ai jamais fait mumuse avec les schedulers.


---------------
« No question is too silly to ask, but, of course, some are too silly to answer. » -- Perl book
Reply

Marsh Posté le 30-08-2002 à 03:02:20    

10 ms, c'est (environ) la durée de temps minimum allouée par le système.
On peut toujours l'abréger avec sleep, mais rien ne garantit que c'est l'autre thread qui aura la main.
 
Approches générales:
-N'avoir qu'un seul thread. Quel intérêt d'en avoir 2 s'ils ne doivent pas s'exécuter en même temps ?
-Créer un troisième thread chargé du travail.
 
Approches Windows:
-Augmenter la priorité de l'autre thread avec SetThreadPriority avant un Sleep(durée 0).
-SwitchToThread, mais il n'y a pas de paramètres.
-ConvertTheadToFiber sur les threads, SwitchToFiber pour passer de l'un à l'autre avec un seul fil d'exécution.
-CreateMutex et WaitForSingleObject.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 02-09-2002 à 14:42:24    

Hello
 
Programmez sous Windows les gas, la fonction Sleep() SDK de Windows, n'endore que le thread qui l'appelle, et pas le processus...
 
Nanannn! je suis pas un pro Windows, loin de là...
 :sol:

Reply

Marsh Posté le 02-09-2002 à 15:51:42    

Sous Linux, j'ai réussi à obtenir un délai de 20µs en mettant l'ordonnancement RR (temps réel) et en me mettant en root. :hap:
Par contre, il y a un gros pb sous linux :
si il y a plusieurs threads ayant une priorité indentique, il sera impossible qu'ils s'exécutent en parallèle (le premier thread s'exécutera, puis le 2ème qd le 1er sera terminé, pui...)
et pire, si un thread fait une boucle infini par exemple pour actualiser l'ITF toutes les secondes, les autres threads de même priorité n'auront jamais la main
 
Pour résumer: si on veut un ordonnancement tps réel on ne pourra pas utiliser des threads :non:

Reply

Marsh Posté le 02-09-2002 à 16:24:23    

yung3001 a écrit a écrit :

Programmez sous Windows les gas, la fonction Sleep() SDK de Windows, n'endore que le thread qui l'appelle, et pas le processus...


C'est bien, tu veux dire que ça marche comme sous Unix ?
 
Tu ne m'as pas convaincu d'acheter une licence de Windows XP, là, essaye encore.


---------------
« No question is too silly to ask, but, of course, some are too silly to answer. » -- Perl book
Reply

Marsh Posté le 02-09-2002 à 16:37:09    

Citation :

C'est bien, tu veux dire que ça marche comme sous Unix ?  
 
Tu ne m'as pas convaincu d'acheter une licence de Windows XP, là, essaye encore.


 
Linux, Solaris, Windows, Mac OS, Amiga OS, BeOS... le tout n'est pas de savoir qui est le meilleurs, mais c'est d'avoir un système qui nous convienne. Windows c'est pas le top (c'est pas un scoop, mais ça s'améliore...quoi que), mais c'est malheureusement la seul plateforme ou tu trouves ce que tu veux quand comme moi (et des millions d'autres): Tu aimes faire de la musique (carte d'extension pro, logiciels pro), tu aimes jouer de temps en temps, programmer un peu pour toi ou ton boulot, lire tes emails, regarder des DVDs, graver, imprimer, utiliser des logiciels pas courant (généalogie...); et tout ça sur la même bécane. Pour ça, y'a que Windows, ou à la rigueur MacOS; pour la zic par exemple, les cartes PCI que j'ai, leur drivers ne fonctionnent que sous Windows.
C'est pas l'envi qui me manque de passer à autre chose, mais ça ne me servirait à rien à part bidouiller. Et au boulot, que du Windows, et du Solaris (mais Solaris à la maison, faut être taré  :pt1cable: ).  
 :bounce:  :bounce:  :bounce:

Reply

Marsh Posté le 02-09-2002 à 17:07:00    

yung3001 a écrit a écrit :

Linux, Solaris, Windows, Mac OS, Amiga OS, BeOS... le tout n'est pas de savoir qui est le meilleurs, mais c'est d'avoir un système qui nous convienne. Windows c'est pas le top (c'est pas un scoop, mais ça s'améliore...quoi que), mais c'est malheureusement la seul plateforme ou tu trouves ce que tu veux quand comme moi (et des millions d'autres): Tu aimes faire de la musique (carte d'extension pro, logiciels pro), tu aimes jouer de temps en temps, programmer un peu pour toi ou ton boulot, lire tes emails, regarder des DVDs, graver, imprimer, utiliser des logiciels pas courant (généalogie...); et tout ça sur la même bécane. Pour ça, y'a que Windows, ou à la rigueur MacOS; pour la zic par exemple, les cartes PCI que j'ai, leur drivers ne fonctionnent que sous Windows.


Hmmmm non, ça ne me convainc pas.
 
Pourquoi tu cherches absolument à me faire passer à Windows ? Tu fais ce que tu veux chez toi, mais de mon point de vue, il n'a que des inconvénients.


---------------
« No question is too silly to ask, but, of course, some are too silly to answer. » -- Perl book
Reply

Marsh Posté le 02-09-2002 à 17:13:03    

yung3001 > les trolls Windows - Linux c'est sur Soft & Reseau et sur OS Alternatifs. Ici ce sont plutôt les trolls concernant les langages. Merci de ne pas polluer avec ce genre de posts inutiles (surtout que Windows t'as pas une précision à la milliseconde près non plus)


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 02-09-2002 à 23:40:36    

sur tru 64 unix il y a un nanaosleep un peut particulier (qui est _NP (nonportable)) et qui permet de n'endormir que le thread apelant mais la pression depant de se qui a ete programmer dans ton noyau (1ms ou plus en fonctionde l'install) sinon sur QNX nanosleep doit fonctionner nickel même pour 1 ms


---------------
la théorie c quant tout dois fonctionner mais rien ne marche                                 la pratique c quant tout marche mais personne ne c pourquoi                           ici on fais un bon compromis rien ne marche et personne ne c pourquoi :D
Reply

Marsh Posté le 02-09-2002 à 23:43:09    

corection de 2 ou 3 faute de frappe C pas pression mais precision et le non du nanosleep C pthread_delay_np


---------------
la théorie c quant tout dois fonctionner mais rien ne marche                                 la pratique c quant tout marche mais personne ne c pourquoi                           ici on fais un bon compromis rien ne marche et personne ne c pourquoi :D
Reply

Marsh Posté le 03-09-2002 à 10:42:51    

erwan_oops a écrit a écrit :

sur tru 64 unix il y a un nanaosleep un peut particulier (qui est _NP (nonportable)) et qui permet de n'endormir que le thread apelant mais la pression depant de se qui a ete programmer dans ton noyau (1ms ou plus en fonctionde l'install) sinon sur QNX nanosleep doit fonctionner nickel même pour 1 ms


Il me semble avoir vu traîner aussi ce genre de trucs (avec des #define spécifiques et des _NP) pour Linux, ce n'est peut-être pas si non-portable...


---------------
« No question is too silly to ask, but, of course, some are too silly to answer. » -- Perl book
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed