PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WINDEV (précédentes versions) → Section critique, sémaphore ???
Section critique, sémaphore ???
Débuté par Marie, 01 mar. 2018 14:52 - 8 réponses
Posté le 01 mars 2018 - 14:52
Bonjour à tous,

Voilà, j'ai un petit soucis que je n'arrives pas à résoudre.
j'ai une procédure globale qui est une boucle qui récupère des infos sur un port TCP/IP en provenance d'un automate.
je traite, organise et sauvegarde ces infos dans le traitement de la procédure, jusque là pas de soucis.
Sur certains évènements en particuliers, je récupère l'info et l'envoie par SMS via un thread.
Tout fonctionne bien sauf si deux envois de SMS se suivent de près, car un deuxième thread se lance alors que le premier n'est pas fini.

Je pensais utiliser les fonctions section critique et/ou sémaphore, mais l'aide n'est pas très explicite à ce sujet et je n'arrives pas à faire utiliser la fonction qui pourtant semble correspondre à mon besoin.

voilà ce que j'ai fait:
dans les déclarations globales de ma procédure, j'ai mis:
SémaphoreCrée("SMS")
ThreadMode(threadSectionCritique)


dans le traitement, le lancement du thread est fait ainsi:
ThreadExecute("thread1",threadNormal,SMS) // appel de la procédure d'envoi des SMS


et la procédure lancée par le thread est ainsi:

Procedure SMS()
SémaphoreDébut("SMS")
sOuvre(5,2000,2000) //ouverture du port COM
sFixeParamètre(5,19200,0,8,0) // paramétrage du port COM
sEcrit(5,"AT+CMGS=06xxxxxxxx"+RC) // envoi par commande AT du numéro à contacter
BOUCLE
SI sDansFileSortie(5) = 0 ALORS SORTIR
FIN
sEcrit(5,sTextesms1 + Caract(26)) //envoi du corp du SMS
BOUCLE
SI sDansFileSortie(5) = 0 ALORS SORTIR
FIN
sFerme(5) // fermeture du port COM
SémaphoreFin("SMS")
FIN


Une âme charitable pourrait-elle m'aider ?
Membre enregistré
939 messages
Popularité : +66 (68 votes)
Posté le 01 mars 2018 - 15:50
bonjour,

SémaphoreDébut() vous retourne un booleen, il faut je pense tester cette valeur

Procedure SMS()
TANTQUE PAS SémaphoreDébut("SMS")
ThreadPause(5)
FIN
sOuvre(5,2000,2000) //ouverture du port COM
sFixeParamètre(5,19200,0,8,0) // paramétrage du port COM
sEcrit(5,"AT+CMGS=06xxxxxxxx"+RC) // envoi par commande AT du numéro à contacter
BOUCLE
SI sDansFileSortie(5) = 0 ALORS SORTIR
FIN
sEcrit(5,sTextesms1 + Caract(26)) //envoi du corp du SMS
BOUCLE
SI sDansFileSortie(5) = 0 ALORS SORTIR
FIN
sFerme(5) // fermeture du port COM
SémaphoreFin("SMS")
FIN


a tester ;)
Message modifié, 01 mars 2018 - 15:50
Membre enregistré
939 messages
Popularité : +66 (68 votes)
Posté le 01 mars 2018 - 16:02
autant pour moi, répondu trop vite

plutôt partir sur des Mutex

en lieu et place des Sémaphores.

A tester.
Posté le 01 mars 2018 - 16:16
Merci Christophe, pouvez vous m'expliquer comment mettre en place les mutex ? j'avais vu aussi cette solution dans l'aide, mais je n'ai pas réussi à la faire fonctionner.
Membre enregistré
939 messages
Popularité : +66 (68 votes)
Posté le 01 mars 2018 - 16:18
Après, vous pouvez également revoir un peu votre méthode, en partant sur un thread qui s'exécutera en boucle et qui sera en charge d'envoyer vos SMS en utilisant une variable de type File.

Une méthode qui ajoutera un élément à votre File.

struct_SMS est une structure
numero est une chaîne
msg est une chaîne
FIN
File_SMS est une File de struct_SMS
ThreadExecute("thr_SMS_Sended",threadNormal,SMS)


Procedure SMS()

MonSMS est un struct_SMS

BOUCLE

ThreadPause(5)

SI Défile(File_SMS,MonSMS) ALORS

sOuvre(5,2000,2000) //ouverture du port COM
sFixeParamètre(5,19200,0,8,0) // paramétrage du port COM
sEcrit(5,"AT+CMGS="+MonSMS.Numero+RC) // envoi par commande AT du numéro à contacter
BOUCLE
SI sDansFileSortie(5) = 0 ALORS SORTIR
FIN
sEcrit(5,MonSMS.msg + Caract(26)) //envoi du corp du SMS
BOUCLE
SI sDansFileSortie(5) = 0 ALORS SORTIR
FIN
sFerme(5) // fermeture du port COM


FIN

FIN
Message modifié, 01 mars 2018 - 16:18
Membre enregistré
939 messages
Popularité : +66 (68 votes)
Posté le 01 mars 2018 - 16:21
et une méthode pour l'ajout d'un nouveau SMS dans la file d'attente

Procedure Envoi_SMS(vp_Numero,vp_Message)

_sms est un struct_sms
_sms.numero=vp_numero
_sms.msg=vp_message

Enfile(File_SMS,_sms)
Posté le 01 mars 2018 - 17:16
Pour les mutex, il faut que j'écrive dans les déclarations globales:
MutexCrée("SMS")


puis que j'écrive la procédure lancée par le thread comme ceci :

Procedure SMS()
MutexDébut("SMS")
sOuvre(5,2000,2000) //ouverture du port COM
sFixeParamètre(5,19200,0,8,0) // paramétrage du port COM
sEcrit(5,"AT+CMGS=06xxxxxxxx"+RC) // envoi par commande AT du numéro à contacter
BOUCLE
SI sDansFileSortie(5) = 0 ALORS SORTIR
FIN
sEcrit(5,sTextesms1 + Caract(26)) //envoi du corp du SMS
BOUCLE
SI sDansFileSortie(5) = 0 ALORS SORTIR
FIN
sFerme(5) // fermeture du port COM
MutexFin("SMS")
FIN


Est-ce bien ça ?
Membre enregistré
939 messages
Popularité : +66 (68 votes)
Posté le 02 mars 2018 - 09:30
Marie a écrit :
Pour les mutex, il faut que j'écrive dans les déclarations globales:
MutexCrée("SMS")


puis que j'écrive la procédure lancée par le thread comme ceci :

Procedure SMS()
MutexDébut("SMS")
sOuvre(5,2000,2000) //ouverture du port COM
sFixeParamètre(5,19200,0,8,0) // paramétrage du port COM
sEcrit(5,"AT+CMGS=06xxxxxxxx"+RC) // envoi par commande AT du numéro à contacter
BOUCLE
SI sDansFileSortie(5) = 0 ALORS SORTIR
FIN
sEcrit(5,sTextesms1 + Caract(26)) //envoi du corp du SMS
BOUCLE
SI sDansFileSortie(5) = 0 ALORS SORTIR
FIN
sFerme(5) // fermeture du port COM
MutexFin("SMS")
FIN


Est-ce bien ça ?


oui ;)
Posté le 14 mars 2018 - 05:40
Bonjour, je reviens ici car le mutex tel que je l'ai écrit ne fonctionne pas, voici le message d'erreur qui apparait:

Erreur à la ligne 158 du traitement Procédure globale attente.
Vous avez appelé la fonction ThreadExécute.
Le nouveau thread 'thread6' doit exécuter la procédure 'SMS' qui est déjà en cours d'exécution par le thread 'thread4'. Pour autoriser plusieurs threads à exécuter la même procédure, il faut paramètrer le mode de gestion des threads par la fonction ThreadMode.