Se connecter avec
S'enregistrer | Connectez-vous

[c++ parallele] pb gestion de delai

Dernière réponse : dans Programmation

Voila je poste ici car je suis sur qu'il y a des chauds et je ne veut pas passer à l'ennemi :D 

Depuis septembre je programme durant mon temps libre des compostants graphique en SDL.
J'ai entre faire une class boutton,menu deroulant, edit ...

J'utilise cette "bibliothèque" dans mon projet reseau dans lequel j'ai besoin d'un composant particulier.

Explication:
Le porjet consiste a créer un chat en reseau. L'utilisateur recoit une demande d'invitation qu'il peut accepter ou refuser.
Le probleme c'est quand il n'est pas devant son pc il ne fait rien. Je veut donc implementer un timeout, si l'utilisateur ne repond pas avant X secondes on repond par defaut "Absent". Ce timeout serait matérialiser par une barre d'avancement (genre les barre de telechargement ... )

Pour cela j'ai comencé à créer une class "delai"
  1. class delai
  2. {
  3. private:
  4. int duree;
  5. short x;
  6. short y;
  7. short nb_case;
  8. Uint32 col_bordure;
  9. Uint32 col_fond;
  10. Uint32 col_bordure_case;
  11. Uint32 col_fond_case;
  12. bool *fin;
  13. pid_t pid;
  14. t_fenetre *fen;
  15. void wait(void);
  16. public:
  17. delai(t_fenetre *fen2,short x2,short y2,int duree2,short nb_case2,Uint32 col_bordure2,Uint32 col_fond2,Uint32 col_bordure_case,Uint32 col_fond_case);
  18.  
  19. int lancer(void);
  20. int lancer(int duree2);
  21.  
  22. int stopper(void);
  23.  
  24. bool est_fini(void);
  25. };


Voici les variables et fonctions que j'ai besoin.

Le problême se situe au niveau du parallelisme. Le "compte a rebour" doit etre gere en parralle car le processus principal doit permettre a l'utilisateur de repondre par oui ou non.

int lancer(void):
fait un fork et lance ds le fils la fonction wait

void wait(void):
utilise des sleep() afin d'actualiser tte les x secondes la bare d'avancement et si le delai est atteint met le booleen fin a vrai et ce ferme (le processus fils)

int stopper():
stoppe le processus fils. Cette fonction est appeler quand l'utilisateur a fait un choix.

Passons au chose serieuse.
Voivi les trois procedures importante:

  1. bool delai::est_fini(void)
  2. {
  3. printf("%d\n",*fin);
  4. return *fin;
  5. }
  6.  
  7.  
  8. int delai::lancer(void)
  9. {
  10. printf("Lancer()\n");
  11. fin=*false;
  12. pid = fork ();
  13. if (pid ==0 )
  14. wait();
  15. else if (pid > 0)
  16. return 1;
  17. else
  18. {
  19. printf("Lancer: erreur le processus n'a pu être créé\n");
  20. return 0;
  21. }
  22. }
  23.  
  24.  
  25. void delai::wait(void)
  26. {
  27. int temp=0;
  28. int x2,y2;
  29. int tour=0;
  30. printf("### duree: %d nb_case: %d\n",duree,nb_case);
  31. printf("### aff_case: %f\n",duree/nb_case);
  32. int aff_case=(int)duree/nb_case;
  33.  
  34. trace_rectangle_plein(fen->surface,x,y,x+4+(nb_case*13),y+18,col_fond);
  35. trace_rectangle(fen->surface,x,y,x+4+(nb_case*13),y+18,col_bordure);
  36. SDL_Flip(fenetre_princ.surface);
  37.  
  38. y2=y+4;
  39.  
  40. while(temp<duree && !fin)
  41. {
  42. if(temp%(aff_case)==0)
  43. {
  44. x2=x+4+(tour*13);
  45. trace_rectangle_plein(fen->surface,x2,y2,x2+10,y2+10,col_fond_case);
  46. trace_rectangle(fen->surface,x2,y2,x2+10,y2+10,col_bordure_case);
  47. SDL_Flip(fenetre_princ.surface);
  48. tour++;
  49. }
  50.  
  51. sleep(1);
  52. temp++;
  53. }
  54. *fin=true;
  55. int ppid = getpid();
  56. kill(ppid,SIGKILL);
  57. }
  58.  
  59.  
  60.  
  61. int delai::stopper(void)
  62. {
  63. fin=true;
  64. kill(pid,SIGKILL);
  65. }



Vous l'aurez compris tous ceci ne fonctionne pas :( 
Pour fonctionner le programme a besoin que les variables de la classe soit partager par les 2 processus ( a cause de la mise a jour du boolleen fin) mais je ne sais pas vraiment si c'est le cas.

Pour fermer le processus la seul methode que j'ai trouve c'est un kill ... :whistle: 

et sinon ben si vous avez des idee, peut etre que j'ai fait n'imp


Avec tous ca j'ai oublié de vous dire le probleme rencontre :D 

Lorsque l'utilisateur repond je fait stopper le delai avec la fonction stoppe (en faite ca le kill quoi), il se retrouve alors affiche entre croche lorsque je fait un ps -aux. Ensuite tous fonctionne normalement :D 

Le probleme c'est lorsque le edlai touche a sa fin et donc que le kill utilise est celui qui est dans wait(), la tous le programme se ferme tous simplement :( 

Autres pages sur : parallele gestion delai

Lassé par la pub ? Créez un compte

bon ok tous fonctionne, enfin presque

le timeout n'est pas prise en compte, le processus fils se termine bien mais le processus principal ne voi pas que le boolleen fin est mise a TRUE :( 
Les 2 processus doivent utiliser des variables differents :( 


J'ai teste en utilisant un pointeur pour le booleen
bool * fin

si j'affiche l'adresse du pointeur, ds les 2 processus j'ai le meme affichage mais pas le mm contenu ds *fin :( 

J'ai mis a jour l'algo du premier post en ajoutant la fonction est_fini()

Yep ca fonctionne avec les thread

Vous pourrez remarquer que j'utilise directement le booleen "fin" pour arreter le thread en cour d'execution.


  1. class delai
  2. {
  3. public:
  4. int duree;
  5. short x;
  6. short y;
  7. short nb_case;
  8. Uint32 col_bordure;
  9. Uint32 col_fond;
  10. Uint32 col_bordure_case;
  11. Uint32 col_fond_case;
  12. bool fin;
  13. pthread_t adr_thread;
  14. t_fenetre *fen;
  15.  
  16. delai(t_fenetre *fen2,short x2,short y2,int duree2,short nb_case2,Uint32 col_bordure2,Uint32 col_fond2,Uint32 col_bordure_case,Uint32 col_fond_case);
  17.  
  18. int lancer(void);
  19. int lancer(int duree2);
  20.  
  21. int stopper(void);
  22.  
  23. bool est_fini(void);
  24. };
  25.  
  26. void *wait(void *del);





  1. void *wait(void *del)
  2. {
  3. delai* del1=(delai *)del;
  4. int x=del1->x;
  5. int y=del1->y;
  6. int nb_case=del1->nb_case;
  7. int duree=del1->duree;
  8. t_fenetre *fen=del1->fen;
  9. Uint32 col_fond=del1->col_fond;
  10. Uint32 col_bordure=del1->col_bordure;
  11. Uint32 col_fond_case=del1->col_fond_case;
  12. Uint32 col_bordure_case=del1->col_bordure_case;
  13.  
  14.  
  15. int temp=0;
  16. int x2,y2;
  17. int tour=0;
  18.  
  19. int aff_case=(int)duree/nb_case;
  20.  
  21. trace_rectangle_plein(fen->surface,x,y,x+4+(nb_case*13),y+18,col_fond);
  22. trace_rectangle(fen->surface,x,y,x+4+(nb_case*13),y+18,col_bordure);
  23. SDL_Flip(fenetre_princ.surface);
  24.  
  25. y2=y+4;
  26.  
  27. while(temp<duree && !del1->fin)
  28. {
  29. if(temp%(aff_case)==0)
  30. {
  31. x2=x+4+(tour*13);
  32. trace_rectangle_plein(fen->surface,x2,y2,x2+10,y2+10,col_fond_case);
  33. trace_rectangle(fen->surface,x2,y2,x2+10,y2+10,col_bordure_case);
  34. SDL_Flip(fenetre_princ.surface);
  35. tour++;
  36. }
  37.  
  38. sleep(1);
  39. temp++;
  40. }
  41. del1->fin=true;
  42.  
  43. }
  44.  
  45.  
  46.  
  47. int delai::lancer(void)
  48. {
  49. fin=false;
  50.  
  51. if(pthread_create(&adr_thread,NULL,wait,(void *)this) !=0)
  52. {
  53. printf("Erreur de création de thread\n");
  54. return 0;
  55. }
  56. return 1;
  57. }
  58.  
  59.  
  60.  
  61. int delai::stopper(void)
  62. {
  63. fin =true;
  64. }
Lassé par la pub ? Créez un compte