Bonjour à tous,
Je suis confronté à un problème d'exécution que je ne comprends pas.
L'explication n'est pas très simple, je vais essayer d'être le plus clair possible.
Je programme un jeu en php, dans ce jeu, tous les évènements (construction, attaque, commerce, etc etc ...) sont traités par le même script, que j'appelle evenement.php.
Dans ce script evenement.php, je traite les evenements de cette facon :
Chaque évènement à un Id, jusque là, tout va bien.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 if(event=="construction") { .. gestion de la construction delete evenement } if(event=="bataille") { .. gestion de la bataille delete evenement }
Mon probleme, c'est qu'environ 1 fois par mois (très aléatoire...), il commence à me traiter un if(event=="bataille") {.. blabla... delete}, et avant qu'il soit fini, donc avant le delete il recommence à me traiter le même evenement.
Une explication plus précise
if(event=="bataille) (je l'appelle thread 1)
{ ... il commence les calculs (thread 1)
... il continu (thread1)
// tout d'un coup, il met en pause le thread 1
if(event==bataille) (il retraite le meme evenement sur un thread 2)
{... il recommence les calculs (thread 2)
... blablabla tout va bien (thread 2)
... delete evenements (thread 2)}
... blabla tout va bien (thread 1)
... je fini tranquille le thread 1)
... delete evenement (thread 2) }
En résumé, il commence à traité un evenement (thread1), et avant que cette evenement ne soit détruit par la fin du script, il met en "pause" le thread 1, lance un thread 2 qui trouve la même tache à faire, l'execute, delete l'evenement, REPREND le thread 1 qui était en pause, et le fini normalement.
Je suis complètement largué ...
Pour ceux qui se demandent comment j'ai trouvé ca, j'ai écrit une fonction de journalisation dans un fichier ascii, qui retrace à l'aide d'une valeur aleatoire alphanumerique quel "thread" effectue les operations.
Une petite copie de ce que j'ai enregistré :
#################### (TF1454)
Debut Bataille Id:5533942 (TF1454)
Attaquant Gagne!!(TF1454)
####################(KM5048)
Debut Bataille Id:5533942 (KM5048)
Erreur de traitement operation 5533942, operation déjà traitée (KM5048);
********************(KM5048);
Les troupes ne sont pas encore rentrees(TF1454)
Fin des troupes qui ne sont pas encore rentrees(TF1454)
Fin Victoire attaquant!!(TF1454)
********************(TF1454)
Quelques commentaires pour que vous compreniez
La valeur entre parenthèse (TF1454) représente le "thread 1" (désolé, je ne sais pas comment l'appeler), et le (KM5048) le "thread 2".
Sachant que le php est monothread, comment est-ce que ca peut arriver ?
Est-il possible que 2 joueurs lancent le même script en même temps, et que du coup l'évenement soit traité 2 fois ? (je croyais avoir compris que non ?)
Sur le coup, avant de journaliser les opérations, je croyais qu'il s'agissait d'un timeout ou autre à un moment dans le script, qu'il ne finissait pas, et que du coup, il relancait le traitement de l'evenement, mais non, le journal ascii indique clairement le numéro du thread (ou numéro d'exécution comme vous voulez), et on voit bien en fait que les 2 operations sont commencées en même temps.
chaque ###### marque le DEBUT du if(even)
chaque ****** marque la FIN du if(event)
Vu que là je ne comprends pas comment ca peut arriver, quelqu'un pourrait m'éclairer svp ?
Partager