PC SOFT

FORUMS PROFESSIONNELS
WINDEVWEBDEV et WINDEV Mobile

Accueil → WINDEV 25 → WD - Multi Threads com Processamento Serial X Processamento Paralelo
WD - Multi Threads com Processamento Serial X Processamento Paralelo
Débuté par BOLLER ADRIANO, 21 juil. 2016 11:21 - 3 réponses
Membre enregistré
3 651 messages
Popularité : +175 (223 votes)
Posté le 21 juillet 2016 - 11:21
Prezados,

Segue 2 exemplos de Multi threads com Processamento Serial e Processamento Paralelo.

O que é mais rápido, serial ou paralelo?

Bom em todas as situações desde comunicação, equipamentos, tarefas o PARALELO é sem sombra de dúvida o mais rápido.

VARIAVEIS USADAS PARA OS DOIS EXEMPLOS
Procedure MaFenêtre()

ghDébut est une Heure

gxEncoursTotal est un numérique // Utilisé dans le traitement séquentiel
gxEncoursTotalParallèle est un numérique <section critique>// Utilisé dans le traitement parallèle



Vejamos primeiro o exemplo de Processamento SERIAL:
####################################################

ghDébut = HeureSys()

TableSupprimeTout(TABLE_Référence)
gxEncoursTotal = 0

POUR TOUT CLIENT

// Ajout de la ligne
nLigne est un entier = TableAjouteLigne(TABLE_Référence,CLIENT.NomClient)

// récupération de l'encours client
xEncours est un numérique = RécupèreEncours(CLIENT.NumClient)

// Ajoute l'encours total
gxEncoursTotal += xEncours

// Mise à jour de l'encours
TABLE_Référence[nLigne].COL_EnCours = xEncours
SI xEncours>5000 ALORS TABLE_Référence[nLigne]..CouleurFond = VertPastel
FIN

hHeureFin est une Heure
duEcart est une Durée = hHeureFin - ghDébut

LIB_Résultat = "En cours total : " + NumériqueVersChaîne(gxEncoursTotal, "6,2fS") + " €"
Info("Terminé, l'encours total est " + NumériqueVersChaîne(gxEncoursTotal, "6,2fS") + " €","Traitement terminé en " + DuréeVersChaîne(duEcart,"SS s LLL") + " ms")
LIB_Durée_Sequentielle = DuréeVersChaîne(duEcart,"SS s LLL") + " ms"


// Permet de récupérer l'encours du client passé en paramètre
Procedure RécupèreEncours(LOCAL nIDClient est un entier)

xEncours est un numérique

// On simule un traitement long (traitement métier)
TraitementLong()

// Sauvegarde de la position dans le fichier
nPosition est un entier = HSauvePosition(CLIENT)

// recherche le client
HLitRecherchePremier(CLIENT,NumClient,nIDClient)

// Stocke son encours pour le renvoyer
xEncours = CLIENT.EnCoursAutorisé

// Retourne à la position d'origine
HRetourPosition(nPosition)

RENVOYER xEncours


OBS.: PARA EXECUTAR ESSE CÓDIGO ACIMA LEVOU DE FORMA SERIAL UM
TOTAL DE 19 SEGUNDOS 365 CENTÉSIMOS EM MEUS TESTES








Vejamos o exemplo de Processamento em Multi Thread PARALELAS:
####################################################

//Processamento em Multi Thread Paralelas
ghDébut = HeureSys()

// Supprime tout le contenu de la table
TableSupprimeTout(TABLE_Référence)

// Vide la variable globale encoursTotal
gxEncoursTotalParallèle = 0

nLigne est entier
tabTaches est tableau de TâcheParallèle
stTache est une TâcheParallèle

POUR TOUT CLIENT
// Ajout de la ligne
nLigne = TableAjouteLigne(TABLE_Référence,CLIENT.NomClient)

// Lance la tâche parallèle
stTache = TâcheParallèleExécute(_AfficheClient,(CLIENT.NumClient,nLigne),tpoCopieLégèreContexteHFSQL)

Ajoute(tabTaches,stTache)
FIN

// Défini la procédure de continuation
TâcheParallèleExécuteAprèsToutes(tabTaches, AfficheTotal,(),tpoThreadPrincipal)



// Récupère les informations d'un client et demande l'affichage des informations
// c'est cette procédure qui est parallélisée
Procedure _AfficheClient(nNumClient, nLigne)

// Récupère l'encours du client
xEncours est un numérique = RécupèreEncours(nNumClient)

gxEncoursTotalParallèle += xEncours

// Affiche l'encours du client dans le champ table, c'est un accès à l'IHM, ça doit être fait dans le thread principal.
ExécuteThreadPrincipal(_AfficheEncours,nLigne,xEncours)



// Permet d'afficher l'encours client dans la ligne de table correspondante
Procedure _AfficheEncours(nLigne,xEncours)

// Affiche l'encours dans la table
TABLE_Référence[nLigne].COL_EnCours = xEncours
// Si l'encours est supérieur à 5000 euros, on l'affiche sur fond vert
SI xEncours>5000 ALORS TABLE_Référence[nLigne]..CouleurFond=VertPastel



Procedure AfficheTotal()

// Affiche l'encours total et l'heure de fin
hHeureFin est une Heure

// Calcul le temps d'exécution
duEcart est une Durée = hHeureFin - ghDébut

Info("Terminé, l'encours total est " + NumériqueVersChaîne(gxEncoursTotalParallèle, "6,2fS") + " €","Traitement terminé en " + DuréeVersChaîne(duEcart,"MM min SS s LLL") + " ms")

// Affiche la durée dans le libellé
LIB_Durée_Parallèle = DuréeVersChaîne(duEcart,"SS s LLL") + " ms"



// Permet de récupérer l'encours du client passé en paramètre
Procedure RécupèreEncours(LOCAL nIDClient est un entier)

xEncours est un numérique

// On simule un traitement long (traitement métier)
TraitementLong()

// Sauvegarde de la position dans le fichier
nPosition est un entier = HSauvePosition(CLIENT)

// recherche le client
HLitRecherchePremier(CLIENT,NumClient,nIDClient)

// Stocke son encours pour le renvoyer
xEncours = CLIENT.EnCoursAutorisé

// Retourne à la position d'origine
HRetourPosition(nPosition)

RENVOYER xEncours



// Résumé : Cette procédure simule un traitement long (traitement réseau, traitement sur internet, ..)
Procedure TraitementLong()

// On simule l'accès au webservice
// On fait une pause de 10 centièmes de secondes
ThreadPause(10)



OBS: É UM POUCO MAIS COMPLEXO O DESENVOLVIMENTO PARALELO MAS O RESULTADO FINAL COMPENSA.
EM MEUS TESTES O TEMPO REDUZIU PARA 1 SEGUNDO E 365 CENTÉSIMOS





BONS ESTUDOS!

:merci:

--
Adriano José Boller
______________________________________________
Consultor e Representante Oficial da
PcSoft no Brasil
+55 (41) 9949 1800
adrianoboller@gmail.com
skype: adrianoboller
http://wxinformatica.com.br/
Membre enregistré
3 651 messages
Popularité : +175 (223 votes)
Posté le 06 juin 2017 - 00:41
PROGRAMAÇÃO PARALELA(CODIGO EM INGLÊS)

MUITO MAIS RAPIDO!

ghDébut = TimeSys()

// Supprime tout le contenu de la table
TableDeleteAll(TABLE_Référence)

// Vide la variable globale encoursTotal
gxEncoursTotalParallèle = 0

nLigne is int
tabTaches is array of ParallelTask
stTache is a ParallelTask

FOR EACH CLIENT
// Ajout de la ligne
nLigne = TableAddLine(TABLE_Référence,CLIENT.NomClient)

// Lance la tâche parallèle
stTache = ParallelTaskExecute(_AfficheClient,(CLIENT.NumClient,nLigne),ptoLightCopyHFSQLContext)

Add(tabTaches,stTache)
END

// Défini la procédure de continuation
ParallelTaskExecuteAfterAll(tabTaches, AfficheTotal,(),ptoMainThread)



// Récupère les informations d'un client et demande l'affichage des informations
// c'est cette procédure qui est parallélisée
Procedure _AfficheClient(nNumClient, nLigne)

// Récupère l'encours du client
xEncours is numeric = RécupèreEncours(nNumClient)

gxEncoursTotalParallèle += xEncours

// Affiche l'encours du client dans le champ table, c'est un accès à l'IHM, ça doit être fait dans le thread principal.
ExecuteMainThread(_AfficheEncours,nLigne,xEncours)



// Permet d'afficher l'encours client dans la ligne de table correspondante
Procedure _AfficheEncours(nLigne,xEncours)

// Affiche l'encours dans la table
TABLE_Référence[nLigne].COL_EnCours = xEncours
// Si l'encours est supérieur à 5000 euros, on l'affiche sur fond vert
IF xEncours>5000 THEN TABLE_Référence[nLigne]..BrushColor=PastelGreen



Procedure AfficheTotal()

// Affiche l'encours total et l'heure de fin
hHeureFin is Time

// Calcul le temps d'exécution
duEcart is Duration = hHeureFin - ghDébut

Info("Terminé, l'encours total est " + NumToString(gxEncoursTotalParallèle, "6,2fS") + " €","Traitement terminé en " + DurationToString(duEcart,"MM min SS s LLL") + " ms")

// Affiche la durée dans le libellé
LIB_Durée_Parallèle = DurationToString(duEcart,"SS s LLL") + " ms"



// Permet de récupérer l'encours du client passé en paramètre
Procedure RécupèreEncours(LOCAL nIDClient is int)

xEncours is numeric

// On simule un traitement long (traitement métier)
TraitementLong()

// Sauvegarde de la position dans le fichier
nPosition is int = HSavePosition(CLIENT)

// recherche le client
HReadSeekFirst(CLIENT,NumClient,nIDClient)

// Stocke son encours pour le renvoyer
xEncours = CLIENT.EnCoursAutorisé

// Retourne à la position d'origine
HRestorePosition(nPosition)

RESULT xEncours



// Résumé : Cette procédure simule un traitement long (traitement réseau, traitement sur internet, ..)
Procedure TraitementLong()

// On simule l'accès au webservice
// On fait une pause de 10 centièmes de secondes
ThreadPause(10)


--
Adriano José Boller
______________________________________________
Consultor e Representante Oficial da
PcSoft no Brasil
+55 (41) 99949 1800
adrianoboller@gmail.com
skype: adrianoboller
http://wxinformatica.com.br/
Membre enregistré
3 651 messages
Popularité : +175 (223 votes)
Posté le 06 juin 2017 - 01:38
Funções para gerenciar as Threads e os Semafros

CriticalSectionEnd Marca o fim de uma seção crítica: o código será executado por outro tópico.

CriticalSectionStart Marca o início de uma seção crítica: nenhum outro segmento será capaz de executar o código, desde que o segmento atual não saia da seção crítica.

EventChange Modifica o status de um sinal.

EventoFechar Fecha um sinal de sincronização entre vários tópicos.

EventCreate Cria um sinal.

EventDestroy Explícitamente destrói um sinal.

EventOpen Abre um sinal de sincronização entre vários tópicos.

EventWait Bloqueia o segmento atual enquanto espera que o sinal especificado seja aberto.

ExecuteMainThread Acelera a execução DO procedimento especificado No segmento principal DO aplicativo.

MutexCreate Explícitamente cria um mutex.

MutexDestroce Destrói explicitamente um mutex.

MutexEnd Sinaliza que o segmento libera o mutex.

MutexStart Bloqueia o segmento atual enquanto espera que o mutex seja liberado.

SemáforoCreado Cria um semáforo.

Semáforo Destruir Destrói explicitamente um semáforo.

SemaphoreEnd Permite que um OU mais segmentos saem da área protegida pelo semáforo.

SemaphoreStart Bloqueia o fio atual até o semáforo ser aberto (o que significa que até um ponto "livre" fica disponível na seção protegida).

ThreadCurrent Retorna o nome DO segmento atualmente executado.

ThreadEnd Termina a execução DO segmento atual.

ThreadExecute Inicia a execução de um tópico secundário.

ThreadMode Muda o modo de gerenciamento de threads.

ThreadPause Pausa o segmento atual durante a duração especificada.

ThreadPersistent Faz um thread persistente.

Linha prioritária Retorna OU modifica o nível de prioridade de um segmento.

ThreadResume Retoma a execução de um segmento que foi interrompido pelo ThreadSuspend .

ThreadSendSignal O segmento atual envia um sinal para a thread especificada para desbloqueá-lo.

ThreadState Retorna o status atual de um segmento.

ThreadStop Pára um fio secundário.

ThreadSuspend Suspende temporariamente a execução DO thread especificado.

ThreadWait Espera o fim da execução da thread especificada.

ThreadWaitSignal Bloqueia o fio atual até receber um sinal de outro segmento.

Você também tem a capacidade de usar os seguintes tipos de variáveis:

Evento automático O tipo AutomaticEvent é usado para gerenciar um sinal automático.

ManualEvent O tipo ManualEvent é usado para gerir um sinal manual.


https://help.windev.com/en-US/…

--
Adriano José Boller
______________________________________________
Consultor e Representante Oficial da
PcSoft no Brasil
+55 (41) 99949 1800
adrianoboller@gmail.com
skype: adrianoboller
http://wxinformatica.com.br/
Message modifié, 06 juin 2017 - 01:39
Membre enregistré
3 651 messages
Popularité : +175 (223 votes)
Posté le 05 avril 2018 - 22:08
Em ingles

Procedure MyWindow()
ghDébut is Time
gxEncoursTotal is numeric // Utilisé dans le traitement séquentiel
gxEncoursTotalParallèle is numeric <critical section>// Utilisé dans le traitement parallèle



//SERIAL
ghDébut = TimeSys()

TableDeleteAll(TABLE_Référence)
gxEncoursTotal = 0

FOR EACH CLIENT

// Ajout de la ligne
nLigne is int = TableAddLine(TABLE_Référence,CLIENT.NomClient)

// récupération de l'encours client
xEncours is numeric = RécupèreEncours(CLIENT.NumClient)

// Ajoute l'encours total
gxEncoursTotal += xEncours

// Mise à jour de l'encours
TABLE_Référence[nLigne].COL_EnCours = xEncours
IF xEncours>5000 THEN TABLE_Référence[nLigne]..BrushColor = PastelGreen
END

hHeureFin is Time
duEcart is Duration = hHeureFin - ghDébut

LIB_Résultat = "En cours total : " + NumToString(gxEncoursTotal, "6,2fS") + " €"
Info("Terminé, l'encours total est " + NumToString(gxEncoursTotal, "6,2fS") + " €","Traitement terminé en " + DurationToString(duEcart,"SS s LLL") + " ms")
LIB_Durée_Sequentielle = DurationToString(duEcart,"SS s LLL") + " ms"


//PARALELO
ghDébut = TimeSys()

// Supprime tout le contenu de la table
TableDeleteAll(TABLE_Référence)

// Vide la variable globale encoursTotal
gxEncoursTotalParallèle = 0

nLigne is int
tabTaches is array of ParallelTask
stTache is a ParallelTask

FOR EACH CLIENT
// Ajout de la ligne
nLigne = TableAddLine(TABLE_Référence,CLIENT.NomClient)

// Lance la tâche parallèle
stTache = ParallelTaskExecute(_AfficheClient,(CLIENT.NumClient,nLigne),ptoLightCopyHFSQLContext)

Add(tabTaches,stTache)
END

// Défini la procédure de continuation
ParallelTaskExecuteAfterAll(tabTaches, AfficheTotal,(),ptoMainThread)


// Récupère les informations d'un client et demande l'affichage des informations
// c'est cette procédure qui est parallélisée
Procedure _AfficheClient(nNumClient, nLigne)

// Récupère l'encours du client
xEncours is numeric = RécupèreEncours(nNumClient)

gxEncoursTotalParallèle += xEncours

// Affiche l'encours du client dans le champ table, c'est un accès à l'IHM, ça doit être fait dans le thread principal.
ExecuteMainThread(_AfficheEncours,nLigne,xEncours)


// Permet d'afficher l'encours client dans la ligne de table correspondante
Procedure _AfficheEncours(nLigne,xEncours)

// Affiche l'encours dans la table
TABLE_Référence[nLigne].COL_EnCours = xEncours
// Si l'encours est supérieur à 5000 euros, on l'affiche sur fond vert
IF xEncours>5000 THEN TABLE_Référence[nLigne]..BrushColor=PastelGreen


Procedure AfficheTotal()

// Affiche l'encours total et l'heure de fin
hHeureFin is Time

// Calcul le temps d'exécution
duEcart is Duration = hHeureFin - ghDébut

Info("Terminé, l'encours total est " + NumToString(gxEncoursTotalParallèle, "6,2fS") + " €","Traitement terminé en " + DurationToString(duEcart,"MM min SS s LLL") + " ms")

// Affiche la durée dans le libellé
LIB_Durée_Parallèle = DurationToString(duEcart,"SS s LLL") + " ms"


// Permet de récupérer l'encours du client passé en paramètre
Procedure RécupèreEncours(LOCAL nIDClient is int)

xEncours is numeric

// On simule un traitement long (traitement métier)
TraitementLong()

// Sauvegarde de la position dans le fichier
nPosition is int = HSavePosition(CLIENT)

// recherche le client
HReadSeekFirst(CLIENT,NumClient,nIDClient)

// Stocke son encours pour le renvoyer
xEncours = CLIENT.EnCoursAutorisé

// Retourne à la position d'origine
HRestorePosition(nPosition)

RESULT xEncours


// Résumé : Cette procédure simule un traitement long (traitement réseau, traitement sur internet, ..)
Procedure TraitementLong()

// On simule l'accès au webservice
// On fait une pause de 10 centièmes de secondes
ThreadPause(10)


--
Adriano José Boller
______________________________________________
Consultor e Representante Oficial da
PcSoft no Brasil
+55 (41) 99949 1800
adrianoboller@gmail.com
skype: adrianoboller
http://wxinformatica.com.br/