* * * *

Privacy Policy

Blog italiano

Clicca qui se vuoi andare al blog italiano su Lazarus e il pascal.

Forum ufficiale

Se non siete riusciti a reperire l'informazione che cercavate nei nostri articoli o sul nostro forum vi consiglio di visitare il
Forum ufficiale di Lazarus in lingua inglese.

Lazarus 1.0

Trascinare un file nel programma
DB concetti fondamentali e ZeosLib
Recuperare codice HTML da pagina web
Mandare mail con Lazarus
Stabilire il sistema operativo
Esempio lista in pascal
File INI
Codice di attivazione
Realizzare programmi multilingua
Lavorare con le directory
Utilizzare Unità esterne
TTreeView
TTreeview e Menu
Generare controlli RUN-TIME
LazReport, PDF ed immagini
Intercettare tasti premuti
Ampliare Lazarus
Lazarus e la crittografia
System Tray con Lazarus
UIB: Unified Interbase
Il file: questo sconosciuto
Conferma di chiusura di un applicazione
Liste e puntatori
Overload di funzioni
Funzioni a parametri variabili
Proprietà
Conversione numerica
TImage su Form e Panel
Indy gestiore server FTP lato Client
PopUpMenu sotto Pulsante (TSpeedButton)
Direttiva $macro
Toolbar
Evidenziare voci TreeView
Visualizzare un file Html esterno
StatusBar - aggirare l'errore variabile duplicata
Da DataSource a Excel
Le permutazioni
Brute force
Indy 10 - Invio email con allegati
La gestione degli errori in Lazarus
Pascal Script
Linux + Zeos + Firebird
Dataset virtuale
Overload di operatori
Lavorare con file in formato JSON con Lazarus
Zeos ... dietro le quinte (prima parte)
Disporre le finestre in un blocco unico (come Delphi)
Aspetto retrò (Cmd Line)
Lazarus 1.0
Come interfacciare periferica twain
Ubuntu - aggiornare free pascal e lazarus
fpcup: installazioni parallele di lazarus e fpc
Free Pascal e Lazarus sul Raspberry Pi
Cifratura: breve guida all'uso dell'algoritmo BlowFish con lazarus e free pascal.
Creare un server multithread
guida all'installazione di fpc trunk da subversion in linux gentoo
Indice
DB concetti fondamentali e connessioni standard
Advanced Record Syntax
DB concetti fondamentali e DBGrid
DB concetti fondamentali e TDBEdit, TDBMemo e TDBText
Advanced Record Syntax: un esempio pratico
Superclasse form base per programmi gestionali (e non)
Superclasse form base per programmi gestionali (e non) #2 - log, exception call stack, application toolbox
Superclasse form base per programmi gestionali (e non) #3 - traduzione delle form
Superclasse form base per programmi gestionali (e non) #4 - wait animation
Un dialog per la connessione al database:TfmSimpleDbConnectionDialog
Installare lazarus su mac osx sierra
immagine docker per lavorare con lazarus e free pascal
TDD o Test-Driven Development
Benvenuto! Effettua l'accesso oppure registrati.
Maggio 15, 2024, 03:56:14 am

Inserisci il nome utente, la password e la durata della sessione.

551 Visitatori, 0 Utenti

Autore Topic: Esecuzione parallela  (Letto 2139 volte)

tito_livio

  • Full Member
  • ***
  • Post: 152
  • Karma: +3/-0
Esecuzione parallela
« il: Giugno 14, 2023, 07:24:37 pm »
Ciao a tutti, ho un dubbio.
Supponiamo di avere un programma Lazarus che ha due bottoni e cliccandoci sopra viene eseguito del codice, diverso, che prende un po' di tempo, per esempio 10 sec.
Se io premo il primo bottone e poi, subito dopo, il secondo, i due sottoprogrammi vengono eseguiti in parallelo?
Io penso di no ma mi sta venendo qualche dubbio.
Grazie a tutti in anticipo.

quack

  • Jr. Member
  • **
  • Post: 71
  • Karma: +7/-0
Re:Esecuzione parallela
« Risposta #1 il: Giugno 14, 2023, 09:47:43 pm »
Le due procedure utilizzerebbero lo stesso thread della form, quindi quello che solitamente succede è che dopo aver premuto il primo pulsante la form si "freezza" (il programma non risponde) e non riesci neanche a premere il secondo pulsante fin quando la prima routine non ha terminato.

Se vuoi una esecuzione in parallelo uno dei metodi è usare i TThread.

Ciao


SO: Fedora\W10
Lazarus: Trunk\3.0
FPC: Trunk\3.2.2

Avogadro

  • Full Member
  • ***
  • Post: 217
  • Karma: +0/-0
Re:Esecuzione parallela
« Risposta #2 il: Giugno 14, 2023, 11:03:01 pm »
Lazarus "Multithreaded Application "

https://wiki.freepascal.org/Multithreaded_Application_Tutorial

La memoria va ai tempi del primo fortran che permetteva il calcolo parallelo e vettoriale:

https://it.wikipedia.org/wiki/Cray-1

Tornando con i piedi per terra e pensando alle cose spiccce , c'è un problema analogo  quando si fanno delle operazioni un attimo piu' complesse su delle tabelle di dati:  il sw si blocca in attesa che il processo termini;   a parte l' uso del del cambiare la "forma" del puntatore del mouse ( https://wiki.freepascal.org/Cursor) fin quando il processo non termina,  si puo' usare l' "application.processmessage" (esempio  https://forum.lazarus.freepascal.org/index.php?topic=46524.0 ) , ma va da sè che tutto è perfettibile : https://www.thoughtco.com/dark-side-of-application-processmessages-1058203 .




« Ultima modifica: Giugno 14, 2023, 11:13:54 pm da Avogadro »

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1272
  • Karma: +43/-0
  • Prima ascoltare, poi decidere
Re:Esecuzione parallela
« Risposta #3 il: Giugno 15, 2023, 12:02:05 am »
Dice bene @Quack, ossia che tutti gli eventi della LCL e non solo vengono gestiti in un unico Thread conosciuto come Thread Principale (Main Thread).

Da quel Thread (SOLO DAL QUEL THREAD !!!) e quindi anche per esteso dagli eventi che certamente vengono gestiti dal Main Thread, si possono gestire le funzioni grafiche o qualunque cosa abbia a che fare con la LCL.

Il Main Thread, se non forzato da tentativi di suicidio con "ProcessMessages" e simili, ESEGUE UN SOLO EVENTO ALLA VOLTA.

Vai nel blog del forum e cerca Thread, troverai un articolo (te le linko qui per comodità: https://blog.lazaruspascal.it/2022/04/24/thread/ )

Ciao
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

tito_livio

  • Full Member
  • ***
  • Post: 152
  • Karma: +3/-0
Re:Esecuzione parallela
« Risposta #4 il: Giugno 15, 2023, 12:10:53 am »
No, non voglio fare il multithread, voglio che le due parti di programma vengano eseguite in tempi separati.
Non uso, in questo caso, "application.processmessage", volevo solo sapere se sicuramente le due parti venivano eseguite in momenti diversi.
Da quello che mi dite la cosa adesso è chiara, i due eventi sono eseguiti uno alla volta, grazie.

bonmario

  • Hero Member
  • *****
  • Post: 1304
  • Karma: +10/-1
Re:Esecuzione parallela
« Risposta #5 il: Giugno 15, 2023, 08:22:13 am »
Il Main Thread, se non forzato da tentativi di suicidio con "ProcessMessages" e simili, ESEGUE UN SOLO EVENTO ALLA VOLTA.

Scusa, per curiosità: a me capita spesso di usare "ProcessMessages" quando sto lanciando un'operazione che può durare parecchio. In pratica, ogni "tot", emetto dei messaggi, e poi un bel "ProcessMessages" per evitare che il programma sembri bloccato.
Ora, supponiamo che io abbia un programma "fatto male" con 2 bottoni, di cui il primo bottone è quello che lancia il processo lungo che dicevo prima.
Mentre questo processo sta ancora girando, io clicco sul secondo bottone.

Cosa succede?
Io ho sempre pensato che partano i lavori del secondo bottone, interrompendo quelli del primo. Quando finiscono le operazioni del secondo bottone, ripartono quelle del primo.
E' corretto?

Grazie, Mario

xinyiman

  • Administrator
  • Hero Member
  • *****
  • Post: 3249
  • Karma: +12/-0
Re:Esecuzione parallela
« Risposta #6 il: Giugno 15, 2023, 08:37:28 am »
Funziona che porta a termine prima il codice del primo bottone che viene premuto.
Per questo motivo è consigliabile pilotare le proprietà .enabled di tutti i componenti della schermata che possono rompere i maroni.
Esempio se ho button1 e button2, se premo su button1 la prima cosa che deve fare è disabilitare l'operatività di button2 e riattivarla solo alla fine del processo.
Così si evitano comportamenti anomali
Ieri è passato, domani è futuro, oggi è un dono...

bonmario

  • Hero Member
  • *****
  • Post: 1304
  • Karma: +10/-1
Re:Esecuzione parallela
« Risposta #7 il: Giugno 15, 2023, 09:05:48 am »
Sì, grazie, di solito faccio così: quando qualcuno clicca su un bottone, disabilito tutti i componenti del dialogo (o la maggior parte di essi), e li riabilito alla fine del suo lavoro.
La mia era solo una curiosità !

Ciao, Mario

nomorelogic

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2875
  • Karma: +20/-4
Re:Esecuzione parallela
« Risposta #8 il: Giugno 15, 2023, 09:34:53 am »
ProcessMessages, di fondo, forza l'elaborazione dei messaggi in coda

per fare questo, interrompe il main thread e, se lo si fa in un loop, può allungare di molto la durata del loop stesso
Imagination is more important than knowledge (A.Einstein)

bonmario

  • Hero Member
  • *****
  • Post: 1304
  • Karma: +10/-1
Re:Esecuzione parallela
« Risposta #9 il: Giugno 15, 2023, 09:52:41 am »
Normalmente si cerca di bilanciare le cose:
- se non lo metti, l'utente può pensare che il programma è bloccato, e ne forza l'arresto (è capitato troppe volte !!!)
- se lo metti, come hai detto tu, rischi di rallentare il processo principale.

Io di solito lo metto o ogni "tot" secondi, o se sto facendo un ciclo su un elenco di files, ogni "tot" files elaborati. In pratica, emetto un messaggio con cui faccio capire all'utente a che punto sono, e poi un bel "ProcessMessages"

Stilgar

  • Global Moderator
  • Hero Member
  • *****
  • Post: 2382
  • Karma: +10/-0
Re:Esecuzione parallela
« Risposta #10 il: Giugno 15, 2023, 11:43:25 am »
Ciao a tutti, ho un dubbio.
Supponiamo di avere un programma Lazarus che ha due bottoni e cliccandoci sopra viene eseguito del codice, diverso, che prende un po' di tempo, per esempio 10 sec.
Se io premo il primo bottone e poi, subito dopo, il secondo, i due sottoprogrammi vengono eseguiti in parallelo?
Io penso di no ma mi sta venendo qualche dubbio.
Grazie a tutti in anticipo.


Ciao Tito.
Cosa intendi di preciso per "sottoprogrammi"?
Se ho intuito correttamente:
vuoi far girare in parallelo parti del processo, devi fare in modo che il "master" richiami l'eseguibile come "slave".
Attraverso dei parametri (riga di comando?) puoi far eseguire un pezzo dell'eseguibile piuttosto che un altro.
In questo modo, con la classe TProcess hai la possibilità di passare sia parametri ed ignorare eventuali "result" dell'elaborazione (vecchio errorcode, per intendeci): modalità spara e dimentica.


Se vuoi recuperare il risultato dell'esecuzione, per lasciare parallela l'esecuzione, mi sa che ti tocca impelagarti con i thread per monitorare in parallelo le esecuzioni, altrimenti il monitorare il risultato porta ad avere una sequenzialità di lancio dei "sottoprogrammi".


Stilgar

Al mondo ci sono 10 tipi di persone ... chi capisce il binario e chi no.

tito_livio

  • Full Member
  • ***
  • Post: 152
  • Karma: +3/-0
Re:Esecuzione parallela
« Risposta #11 il: Giugno 15, 2023, 05:49:33 pm »
Per questo motivo è consigliabile pilotare le proprietà .enabled di tutti i componenti della schermata che possono rompere i maroni.
Esempio se ho button1 e button2, se premo su button1 la prima cosa che deve fare è disabilitare l'operatività di button2 e riattivarla solo alla fine del processo.
Così si evitano comportamenti anomali

Ciao Xinyiman
Io, in questo mio caso, non uso "ProcessMessages".
Quindi, essendo che dopo la pressione di button1 non è possibile cliccare altri bottoni perché è tutto freezzato fino alla fine dell'esecuzione del thread di button1, credo si possa anche non disabilitare gli altri bottoni.
Certo, se l'utente si mette a cliccare qui e là magari altri thread vengono messi in coda ma mai esegiuiti concorrentemente.

Cosa intendi di preciso per "sottoprogrammi"?
Se ho intuito correttamente:
vuoi far girare in parallelo parti del processo, devi fare in modo che il "master" richiami l'eseguibile come "slave".

Ciao Stilgar
Per sottoprogramma intendo il codice (o thread) associato alla pressione di un bottone.
Comunque io non voglio far girare in parallelo nessun processo, anzi volevo essere sicuro che, anche se si cliccava button1 e poi subito dopo button2, l'esecuzione dei due thread fosse avvenuta una alla volta.
Poi @quack e @DragoRosso mi hanno chiarito che effetivamente è così, cioè l'esecuzione avviene sequenzialmente.

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1272
  • Karma: +43/-0
  • Prima ascoltare, poi decidere
Re:Esecuzione parallela
« Risposta #12 il: Giugno 16, 2023, 08:09:32 am »
......
Per sottoprogramma intendo il codice (o thread) associato alla pressione di un bottone.
......

Ciao, occhio che la pressione del bottone non genera "thread" nè il codice normale "abbinato" è un thread. Il codice abbinato all'evento "gira" all'interno del MAIN THREAD (che però è un thread particolare per la sua funzione).
Il Thread è un processo diciamo autonomo con una sua vita. Ad esempio i thread usati dai componenti di comunicazione, e i loro eventi (come quando arriva un dato) generalmente girano in un thread autonomo (non nel MAIN THREAD per via delle prestazioni normalmente).

E' solo una precisazione per cercare di fare capire meglio il concetto di thread, "non me ne vogliate"  ;)
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1272
  • Karma: +43/-0
  • Prima ascoltare, poi decidere
Re:Esecuzione parallela
« Risposta #13 il: Giugno 16, 2023, 08:52:12 am »
Scusa, per curiosità: a me capita spesso di usare "ProcessMessages" quando sto lanciando un'operazione che può durare parecchio. In pratica, ogni "tot", emetto dei messaggi, e poi un bel "ProcessMessages" per evitare che il programma sembri bloccato.
Ora, supponiamo che io abbia un programma "fatto male" con 2 bottoni, di cui il primo bottone è quello che lancia il processo lungo che dicevo prima.
Mentre questo processo sta ancora girando, io clicco sul secondo bottone.
Cosa succede?
Io ho sempre pensato che partano i lavori del secondo bottone, interrompendo quelli del primo. Quando finiscono le operazioni del secondo bottone, ripartono quelle del primo.
E' corretto?
Grazie, Mario

Funziona che porta a termine prima il codice del primo bottone che viene premuto.
Per questo motivo è consigliabile pilotare le proprietà .enabled di tutti i componenti della schermata che possono rompere i maroni.
Esempio se ho button1 e button2, se premo su button1 la prima cosa che deve fare è disabilitare l'operatività di button2 e riattivarla solo alla fine del processo.
Così si evitano comportamenti anomali

ProcessMessages, di fondo, forza l'elaborazione dei messaggi in coda
per fare questo, interrompe il main thread e, se lo si fa in un loop, può allungare di molto la durata del loop stesso

L'uso di ProcessMessages genera ben altro, oltre a quanto descritto. Di fatto il suo uso altera la sequenza di esecuzione del MAIN THREAD e può avere effetti difficili da diagnosticare.
Windows si basa sui "messaggi" e molto di ciò che lo riguarda comporta la gestione dei messaggi: un tasto premuto genera un messaggio (anzi più di uno), altri eventi di sistema (ad esempio la chiusura di una form) generano messaggi.

Potrebbe non bastare la disattivazione dei componenti attivi grafici: provate a pensare cosa succede se premo CTRL F4 (dovrebbe chiudere una dialog box aperta) o altri "tasti di sistema" mentre sono a gestire un evento nel thread principale e uso ProcessMessages in quella dialog box ...

Non usate ProcessMessages se non ne avete l'assoluta necessità e ormai tale funzione potrebbe essere tranquillamente "eliminata". Cercate invece di usare le tecniche che ci sono e ormai tali tecniche non hanno segreti o parti oscure ... l'uso dei thread o di altri sistemi per l'esecuzione asincrona di codice particolarmente pesante o lungo risolve tranquillamente il problema del "congelamento" della parte grafica.

Così come si dovrebbe evitare loop "infiniti" (infiniti per modo di dire ovviamente) all'interno del codice: gli eventi risolvono molto spesso benissimo tali casistiche (così come anche i semafori).

Il SO poi farà effettivamente dei loop, ma insieme a mille altre cose non sprecando energie per magari testare in loop una variabile boolena finchè non cambia stato.

Codice: [Seleziona]
var
   test: boolean;

test := true;

//Il codice gira "a manetta" finchè la variabile non diventa false, se fatto in un evento delle LCL il programma si congelerà (oltre che vedere schizzare l'uso della CPU alle stelle).
while test do
   ;

//Peggio che mai fare

while test do
  Application.ProcessMessages;

.....
.....

Ciao ciao
« Ultima modifica: Giugno 16, 2023, 08:55:25 am da DragoRosso »
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

Avogadro

  • Full Member
  • ***
  • Post: 217
  • Karma: +0/-0
Re:Esecuzione parallela
« Risposta #14 il: Giugno 16, 2023, 11:01:39 pm »
"Non usate ProcessMessages se non ne avete l'assoluta necessità e ormai tale funzione potrebbe essere tranquillamente "eliminata""

Parlo per il caso della mia applicazione rigurdante le carte di controllo di  Shewhart*.

In pratica i dati di una macchina (un centinaio per volta)  vengono copiati , con un banale cut and paste del logout strumentale, in un memo (per semplicità, per non dover gestire file testo et similia) , da lì viene poi fatto il "pump data" in  delle tabelle sqllite (con zeoslib) .

Ma mano che i dati vengono caricati il sw fa delle operazioni matematiche (le normali cose di statistica, media, range etc, tutte cose già implementate in dmath) .

Ovviamente per caricare un centinaio di dati il sw ci mette un po' di tempo - un modesto pc da ipermercato  è mica il cray o il cdc - , e per evitare casini tengo traccia facendo scivere nella status bar, ad ogni passo del loop, il numero di righe/record processati ; il punto è che se non uso l'application.processmessage, per deprecata che sia, le scritte nella status bar non si aggiornano man mano, ma vengono su di colpo alla fine del loop, quindi non servono a nulla  .

Si in lazarus  c'è la progress bar,  ma i tentativi di usarla non sono andati a buon fine, mi cospargo il capo di cenere.

Approcci alternativi che evitino l' uso di application.processmessage per questa situazione  ?

Ossia come tenere  traccia a video del numero di righe/record processati per prevenire  i casini da " ma si è bloccato il pc ? cntr-alt-canc " ? 

Si, sqllite è robusto **, ma è meglio prevenire ***.



*
https://www.itl.nist.gov/div898/handbook/pmc/section3/pmc321.htm

**
https://www.sqlitetutorial.net/sqlite-transaction/


***
con delphi, bdbe e paradox ogni 5 minuti saltavano gli indici, si doveva ricorre all' apposito software "ripara tabelle di paradox"; all' epoca si trovava in un attimo free sul web, oggi sul web ci sono  sono depliants pubblicitari .
« Ultima modifica: Giugno 16, 2023, 11:26:48 pm da Avogadro »

 

Recenti

How To

Utenti
Stats
  • Post in totale: 18817
  • Topic in totale: 2240
  • Online Today: 580
  • Online Ever: 900
  • (Gennaio 21, 2020, 08:17:49 pm)
Utenti Online
Users: 0
Guests: 551
Total: 551

Disclaimer:

Questo blog non rappresenta una testata giornalistica poiché viene aggiornato senza alcuna periodicità. Non può pertanto considerarsi un prodotto editoriale ai sensi della legge n. 62/2001.