Historique des modifications - Message

Message #699

Sujet: Threads Linux et Windows


Type Date Auteur Contenu
Dernière modification 04-01-2007 11:26:28 Jerry Kan
[Attention certaines parties de ce tuto ont été mis a jours : Code exemple thread, et Ajout des pthreads-win32 ]

salut,

suite a la discussion sur les threads windows / linux dans le topic routines/Ode-Irrlicht, je poste ici un mini tutoriel sur la facon de faire des threads portables (oupas)

je ne suis pas l'auteur des codes proposés


une methode interressante est d'utiliser les threads posix sous windows en ajoutant la dll Pthread disponible sous licence LGPL ici (merci a Xavier Leroy, Ben Elliston, John Bossom et Ross Johnson) :

http://sourceware.org/pthreads-win32/

(a noter qu'il existe des bibliotheques qui proposent leur propres threads (ex: Boost), et que ceux ci sont parfois portables )


THREAD POSIX PORTABLES :

le code qui suit a été modifié le 4/01/2007 , il est compatible windows linux (testé sous Fedora Core, et Windows XP) , moyennant l'utilisation des dll pthrads disponibles ici : ftp://sourceware.org/pub/pthreads-win32/pthreads-2003-08-19.exe

la procédure d'installation des dll windows est décrite ci apres

un zip regroupant l'exemple ci dessous et tous les fichiers requis est disponible ici :

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

/*
    * C compiler: cc -lpthread pthread1.c
      or
    * C++ compiler: g++ -lpthread pthread1.c 

*/


void *print_message_function( void *ptr );

main()
{
     pthread_t thread1, thread2;
     char *message1 = "Thread 1";
     char *message2 = "Thread 2";
     int  iret1, iret2;

    /* Create independent threads each of which will execute function */

     iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
     iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);

     /* Wait till threads are complete before main continues. Unless we  */
     /* wait we run the risk of executing an exit which will terminate   */
     /* the process and all threads before the threads have completed.   */

     pthread_join( thread1, NULL);
     pthread_join( thread2, NULL); 

     printf("Thread 1 returns: %d\
",iret1);
     printf("Thread 2 returns: %d\
",iret2);
     exit(0);
}

void *print_message_function( void *ptr )
{
  char *message;int i;  message = (char *) ptr;

  for(i=0;i<20000000;i++){
    if(i%1000000 == 0)
      printf("%s \
", message);
  }
  


}

Compilation sous Linux

la plupart des distribs comportent les threads posix, aucun install n'est requise, tapez simplement :
langage C
    cc -lpthread pthread1.c
langage C++
    g++ -lpthread pthread1.c

Compilation sous windows avec Dev C++
(c'est a peut pres pareil avec Code::Block a la différence pret qu'il faut aller dans "linker")

telechargez la derniere version de pthread-w32-v-v-v-release.exe a cette adresse ftp://sourceware.org/pub/pthreads-win32/

cliquez sur l'exe, c'est un auto extractable qui produit 3 dossiers : Pre-built, pthread, et QueueUserAPCEx
seul Prebuild nous interresse,

allez dans Pre-built\\include
prenez les 3 .h et copiez les dans DevCpp\\include\\

allez dans Pre-built\\lib
prenez les 4 .a et .lib et copiez les dans DevCpp\\lib

toujours dans Pre-built\\lib
prenez les 4 .dll et copiez les dans Dev-Cpp/bin


Creez un projet


Allez dans Projet/option du projet/ choisissez l'onglet parametre

cliquez sur "ajouter fichier", trouvez les .lib et les .a et ajoutez les
(il s'agit de libpthreadGC1.a, libpthreadGCE1.a , pthreadVC1.lib, pthreadVSE1.lib )

si vous avez du mal a les retrouver dans DevCpp\\lib, vous pouvez aussi copier les .lib et les .a dans le repertoire projet (ou ailleur) et les lier de la meme facon


compilez, et c'est pret !




[remarque]
si ca ne marche pas, il est tres possible que ce soit parce que votre repertoire DevCpp n'est pas définit dans le path du systeme, la solution la plus simple est de copier les dll dans windows\\system32



exemples

Pour ceux que ca interresse, je met aussi un lien vers un mini projet de jeu (pacman) fonctionnel et compilable (linux) qui utilise des pthreads est dispo ici :

http://www710.univ-lyon1.fr/~jciehl/Public/educ/lil/2004/ostp8_pacman.tar.gz
http://www710.univ-lyon1.fr/~jciehl/Public/educ/lil/2004/ostp8.html


un autre exemple :(merci a Xter):
http://www.cppfrance.com/codes/WIN32-LINUX-THREADS-CPLUSPLUS_19908.aspx



Je termine avec quelques généralités sur les threads qui interresseront peut etre ce qui n'en ont jamais utilisé :

Programmation Concurrente :

l'utilisation de threads suppose le plus souvent une coordination des threads (cas typique du producteur/consommateur ) ansi qu'un acces réglementé a certaine données, (on ne veux pas deux threads accedent en meme temps a une meme structure de donnée (par souci de cohérence, si la structure passe par un etat incohérent lors d'une modification)

les threads posix offrent des fonctionnalités (en plus du thread actif/pause/stop) pour coordonner l'execution des threads, comme par exemple des mutex qui controlent l'acces a des ressources ou des activations / desactivations multiples

Pourquoi il vaut mieux s'en passer ?

L'utilisation des threads est a éviter autant que possible si une version "linéaire" est facilement concevable, en effet la preuve d'un algorithme non linéraire est tres difficile a faire, le debuggage est beaucoup plus difficile, ce n'est pas parce que le programme comporte plusieurs objet qui font des opérations simultanée qu'il est interressant de faire des threads

Autre probleme posé par les threads, il est impossible de garantir que chaque threads recoit un temps d'execution CPU identique aux autres, (le contraire est meme probable), parce que le systeme gere l'ordonancement de chaque threads selon sa propre logique, laquelle varie fonction des disponibilités du systemes

L'utilisation des Thread est a réserver pour les applications qui nécéssitent une réactivité concurrente, dans un serveur, ou une application graphique, le programme doit répondre rapidement a une requette quelque soit sa tache courante
(quand Office sauvegarde votre texte pendant 30sec, vous voulez quand meme pouvoir continuer a le taper)


Comment s'en passer ?

Il vaut donc mieux éviter de creer un jeu ou chaque personnage est un thread, car on court le risque de voir certains personnage agir plus rapidement que d'autres
La meilleure solution pour garantir un temps constant est d'implementer une liste des personnages, de parcourir chaque élément en appelant une méthode que nous a pouvons appeler "agir()" qui effectue un micro mouvement du perso

si la méthode "agir" est suceptible s'execter plus ou moins vite selon le contexte (si le personnage fait du pathfinding par exemple, il peut trouver son chemin plus ou moins vite selon la complexité du terrain) la solution est de choisir le temps a attendre, noter le temps courant avant et apres l'action, et d'attendre une certaine durée tampon pour qu'il y ait toujours le meme intervalle de temps entre deux appels de "agir"


voila, j'espere que j'ai pas raconté trop de bétises
Création du message 10-12-2006 12:28:10 Jerry Kan
[Attention certaines parties de ce tuto ont été mis a jours : Code exemple thread, et Ajout des pthreads-win32 ]

salut,

suite a la discussion sur les threads windows / linux dans le topic routines/Ode-Irrlicht, je poste ici un mini tutoriel sur la facon de faire des threads portables (oupas)

je ne suis pas l'auteur des codes proposés


une methode interressante est d'utiliser les threads posix sous windows en ajoutant la dll Pthread disponible sous licence LGPL ici (merci a Xavier Leroy, Ben Elliston, John Bossom et Ross Johnson) :

http://sourceware.org/pthreads-win32/

(a noter qu'il existe des bibliotheques qui proposent leur propres threads (ex: Boost), et que ceux ci sont parfois portables )


THREAD POSIX PORTABLES :

le code qui suit a été modifié le 4/01/2007 , il est compatible windows linux (testé sous Fedora Core, et Windows XP) , moyennant l'utilisation des dll pthrads disponibles ici : ftp://sourceware.org/pub/pthreads-win32/pthreads-2003-08-19.exe

la procédure d'installation des dll windows est décrite ci apres

un zip regroupant l'exemple ci dessous et tous les fichiers requis est disponible ici :

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

/*
    * C compiler: cc -lpthread pthread1.c
      or
    * C++ compiler: g++ -lpthread pthread1.c 

*/


void *print_message_function( void *ptr );

main()
{
     pthread_t thread1, thread2;
     char *message1 = "Thread 1";
     char *message2 = "Thread 2";
     int  iret1, iret2;

    /* Create independent threads each of which will execute function */

     iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
     iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);

     /* Wait till threads are complete before main continues. Unless we  */
     /* wait we run the risk of executing an exit which will terminate   */
     /* the process and all threads before the threads have completed.   */

     pthread_join( thread1, NULL);
     pthread_join( thread2, NULL); 

     printf("Thread 1 returns: %d\
",iret1);
     printf("Thread 2 returns: %d\
",iret2);
     exit(0);
}

void *print_message_function( void *ptr )
{
  char *message;int i;  message = (char *) ptr;

  for(i=0;i<20000000;i++){
    if(i%1000000 == 0)
      printf("%s \
", message);
  }
  


}

Compilation sous Linux

la plupart des distribs comportent les threads posix, aucun install n'est requise, tapez simplement :
langage C
    cc -lpthread pthread1.c
langage C++
    g++ -lpthread pthread1.c

Compilation sous windows avec Dev C++
(c'est a peut pres pareil avec Code::Block a la différence pret qu'il faut aller dans "linker")

telechargez la derniere version de pthread-w32-v-v-v-release.exe a cette adresse ftp://sourceware.org/pub/pthreads-win32/

cliquez sur l'exe, c'est un auto extractable qui produit 3 dossiers : Pre-built, pthread, et QueueUserAPCEx
seul Prebuild nous interresse,

allez dans Pre-built\\include
prenez les 3 .h et copiez les dans DevCpp\\include\\

allez dans Pre-built\\lib
prenez les 4 .a et .lib et copiez les dans DevCpp\\lib

toujours dans Pre-built\\lib
prenez les 4 .dll et copiez les dans Dev-Cpp/bin


Creez un projet


Allez dans Projet/option du projet/ choisissez l'onglet parametre

cliquez sur "ajouter fichier", trouvez les .lib et les .a et ajoutez les
(il s'agit de libpthreadGC1.a, libpthreadGCE1.a , pthreadVC1.lib, pthreadVSE1.lib )

si vous avez du mal a les retrouver dans DevCpp\\lib, vous pouvez aussi copier les .lib et les .a dans le repertoire projet (ou ailleur) et les lier de la meme facon


compilez, et c'est pret !




[remarque]
si ca ne marche pas, il est tres possible que ce soit parce que votre repertoire DevCpp n'est pas définit dans le path du systeme, la solution la plus simple est de copier les dll dans windows\\system32



exemples

Pour ceux que ca interresse, je met aussi un lien vers un mini projet de jeu (pacman) fonctionnel et compilable (linux) qui utilise des pthreads est dispo ici :

http://www710.univ-lyon1.fr/~jciehl/Public/educ/lil/2004/ostp8_pacman.tar.gz
http://www710.univ-lyon1.fr/~jciehl/Public/educ/lil/2004/ostp8.html


un autre exemple :(merci a Xter):
http://www.cppfrance.com/codes/WIN32-LINUX-THREADS-CPLUSPLUS_19908.aspx



Je termine avec quelques généralités sur les threads qui interresseront peut etre ce qui n'en ont jamais utilisé :

Programmation Concurrente :

l'utilisation de threads suppose le plus souvent une coordination des threads (cas typique du producteur/consommateur ) ansi qu'un acces réglementé a certaine données, (on ne veux pas deux threads accedent en meme temps a une meme structure de donnée (par souci de cohérence, si la structure passe par un etat incohérent lors d'une modification)

les threads posix offrent des fonctionnalités (en plus du thread actif/pause/stop) pour coordonner l'execution des threads, comme par exemple des mutex qui controlent l'acces a des ressources ou des activations / desactivations multiples

Pourquoi il vaut mieux s'en passer ?

L'utilisation des threads est a éviter autant que possible si une version "linéaire" est facilement concevable, en effet la preuve d'un algorithme non linéraire est tres difficile a faire, le debuggage est beaucoup plus difficile, ce n'est pas parce que le programme comporte plusieurs objet qui font des opérations simultanée qu'il est interressant de faire des threads

Autre probleme posé par les threads, il est impossible de garantir que chaque threads recoit un temps d'execution CPU identique aux autres, (le contraire est meme probable), parce que le systeme gere l'ordonancement de chaque threads selon sa propre logique, laquelle varie fonction des disponibilités du systemes

L'utilisation des Thread est a réserver pour les applications qui nécéssitent une réactivité concurrente, dans un serveur, ou une application graphique, le programme doit répondre rapidement a une requette quelque soit sa tache courante
(quand Office sauvegarde votre texte pendant 30sec, vous voulez quand meme pouvoir continuer a le taper)


Comment s'en passer ?

Il vaut donc mieux éviter de creer un jeu ou chaque personnage est un thread, car on court le risque de voir certains personnage agir plus rapidement que d'autres
La meilleure solution pour garantir un temps constant est d'implementer une liste des personnages, de parcourir chaque élément en appelant une méthode que nous a pouvons appeler "agir()" qui effectue un micro mouvement du perso

si la méthode "agir" est suceptible s'execter plus ou moins vite selon le contexte (si le personnage fait du pathfinding par exemple, il peut trouver son chemin plus ou moins vite selon la complexité du terrain) la solution est de choisir le temps a attendre, noter le temps courant avant et apres l'action, et d'attendre une certaine durée tampon pour qu'il y ait toujours le meme intervalle de temps entre deux appels de "agir"


voila, j'espere que j'ai pas raconté trop de bétises

Retour

Options Liens officiels Caractéristiques Statistiques Communauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1440 sujets
11337 messages
Dernier membre inscrit: Saidov17
192 invités en ligne
membre en ligne: -
RSS Feed