Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: bonmario - Settembre 17, 2012, 01:35:39 pm

Titolo: Lavorare con i thread
Inserito da: bonmario - Settembre 17, 2012, 01:35:39 pm
Ciao a tutti,
ho un programma che sfrutta un eseguibile esterno per convertire tutti i fiels mp3 in una directory. Praticamente mi faccio l'elenco dei files e poi, uno alla volta, tramite un TProcess, li faccio ricodificare.
Ho provato con una directory di circa 300 fles e ci ha messo quasi un'ora, quindi avevo pensato di velocizzare il tutto lanciando le ricodifiche in parallelo sfruttando i thread, lanciando una decina di ricodifiche in parallelo.
Fino ad ora però ho usato poco i thread e tra l'altro mai in parallelo.
Volevo quindi chiedervi, devo gestire io a programma il n° di thread che possono girare in parallelo o devo impostare qualche variabile?

Grazie in anticipo, Mario
Titolo: Re:Lavorare con i thread
Inserito da: nomorelogic - Settembre 17, 2012, 01:49:12 pm
ciao,
secondo me se eviti il "wait for terminate", in modo da lanciarli asincronalmente, puoi tranquillamente istanziare 10 TProcess e lanciarli l'uno dietro l'altro.

Ad esempio puoi usare una TObjectList per istanziare e referenziare i 10 (anche 'N' volendo) TProcess. Fatto questo puoi lanciarli uno di seguito all'altro e, nell'OnTerminate di ogni TProcess, ci metti il prelevamento del prossimo file dalla lista.
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Settembre 18, 2012, 01:39:00 pm
Ho fatto un programma di test e sembra funzionare tutto !!!
Alla fine, per lacune mie, ho ripiegato su un array di thread invece di usare la TObjectList.

P.S. Qualcuno sa dirmi come valutare come impostare il n° massimo di thread contemporanei? Ho provato con 20 ed il PC sembra reggere, ma siccome il programma dovrà girare anche su altri PC più o meno potenti, volevo evitare di sovradimensionare tale numero.

Grazie ancora, Mario
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Settembre 25, 2012, 09:08:42 am
Ciao a tutti,
sto facendo i miei esperimenti sui thread. Allego i sorgenti del progetto di prova.
C'è una cos che proprio non capisco ed è a riga 193, proprio dove c'è il breakpoint impostato.
Praticamente, se all'interno dell'execute del thread, lascio attiva la "Application.ProcessMessages", il thread termina all'istante. Se invece disattivo la ProcessMessages, sembra funzionare tutto correttamente.
Chiedo a voi che siete più esperti di me: è un bug o è normale questo comportamento?

Grazie in anticipo, Mario
Titolo: Re:Lavorare con i thread
Inserito da: Stilgar - Settembre 25, 2012, 09:51:19 am
Eseguiendo il codice (eliminando i bp) ottengo questo output ... a me sembra lento a chiudere, ma lavora ;)

File n°:   1  -   Thread n°:  1 -
File n°:   2  -   Thread n°:  2 -
File n°:   3  -   Thread n°:  3 -
File n°:   5  -   Thread n°:  4 -
File n°:   4  -   Thread n°:  1 -
File n°:   7  -   Thread n°:  3 -
File n°:   8  -   Thread n°:  4 -
File n°:   9  -   Thread n°:  1 -
File n°:  10  -   Thread n°:  3 -
File n°:  11  -   Thread n°:  4 -
File n°:  12  -   Thread n°:  1 -
File n°:  17  -   Thread n°:  7 -
File n°:  19  -   Thread n°:  9 -
File n°:  21  -   Thread n°:  1 -
File n°:  22  -   Thread n°:  7 -
File n°:  23  -   Thread n°:  9 -
File n°:  15  -   Thread n°:  5 -
File n°:  25  -   Thread n°:  7 -
File n°:  27  -   Thread n°:  5 -
File n°:  24  -   Thread n°:  1 -
File n°:  13  -   Thread n°:  3 -
File n°:  28  -   Thread n°:  7 -
File n°:  29  -   Thread n°:  5 -
File n°:  32  -   Thread n°:  7 -
File n°:  33  -   Thread n°:  5 -
File n°:  31  -   Thread n°:  3 -
File n°:  35  -   Thread n°:  5 -
File n°:  36  -   Thread n°:  3 -
File n°:  37  -   Thread n°:  5 -
File n°:  38  -   Thread n°:  3 -
File n°:  39  -   Thread n°:  5 -
File n°:  34  -   Thread n°:  7 -
File n°:  40  -   Thread n°:  3 -
File n°:  41  -   Thread n°:  5 -
File n°:  42  -   Thread n°:  7 -
File n°:  30  -   Thread n°:  1 -
File n°:  44  -   Thread n°:  5 -
File n°:  45  -   Thread n°:  7 -
File n°:  43  -   Thread n°:  3 -
File n°:  26  -   Thread n°:  9 -
File n°:  49  -   Thread n°:  7 -
In attesa che tutti i thread terminino il proprio lavoro ...
File n°:  47  -   Thread n°:  5 -
File n°:  50  -   Thread n°:  9 -
File n°:  20  -   Thread n°: 10 -
File n°:  18  -   Thread n°:  8 -
File n°:  48  -   Thread n°:  3 -
File n°:  16  -   Thread n°:  6 -
File n°:  14  -   Thread n°:  4 -
File n°:   6  -   Thread n°:  2 -
File n°:  46  -   Thread n°:  1 -
Il thread n° 1 ha appena finito il proprio lavoro
Fine !!!



Files analizzati: 50
Durata del ciclo: 00:00:14
Invece di:        00:12:30

Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Settembre 25, 2012, 10:00:58 am
Prova ad eseguirlo in debug con il breakpoint sul ProcessMessages.
Con il ProcessMessages attivo, l'istruzione Sleep non viene mai eseguita, ne' tantomeno tittoo quello che c'è dopo "Application.ProcessMessages;".
Se invece disattivi la Application.ProcessMessages e ti rimetti in debug, viene eseguito tutto. Tra l'altro questa cosa non l'ho notata a casa su Linux.

Ciao, Mario
Titolo: Re:Lavorare con i thread
Inserito da: Stilgar - Settembre 25, 2012, 10:14:20 am
Con i bp mi va in malora Lazarus ... sembra che il debugger sotto win7 abbia qualche difficoltà con i thread ...
Piuttosto notavo 2 cose nel codice:
1) No usi tutte le proprerties della classe thread.
2) Gestisci 2 array, al posto di 1 solo (visto che non interroghi il le properties dei thread non vedo altre strade).
Domanda:
  Come mai hai detto al thread di siucidarsi al termine? Dopo lo recicli .. o non ci ho capito una madonna?
Puoi reimpostare i dati e andare a rilanciarlo (cerca thread libero per intendeci).
La WaitFor sul primo non "terminato" fa si che ti scappi completamente il controllo dei thread.
In questi casi (almeno io faccio così) creao 2 classi.
Un monitor che li controlli e il thread specifico.
Il Thread comunica in modo asincorno lo stato al monitor.
L'applicazione chiede al monitor cosa stanno facendo i thread.
La tua form, in questo caso è il monito in questione. Il fatto che il thread decida autonomamente di suicidarsi va contro l'idea dei thread pool.
Quando deallochi il monitor, questo dealloca il pool di thread.
Se si suoicidano, li sganci e te ne dimentichi.
Sono proprio curioso di sapere come mai nn hai deciso di usare il terminated del thread.
;)
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Settembre 25, 2012, 10:38:51 am
Sono un novizio dei thread ... ho messo insieme informazioni prese da vari siti.
Dico al thread di suicidarsi perché voglio riciclare i thread quando terminano. Nella "TMyThread.Destroy;" ho aggiunto l'istruzione che va ad impostare il thread come terminato nell'array di controllo che uso.
La WaitFor la faccio solo al termine del ciclo principale, in modo che il programma resti in attesa fino a quando tutti i thred in esecuzione non sono terminati.

Per quanto riguarda il discorso del processmessages, prova così:
Codice: [Seleziona]
  procedure TMyThread.Execute;
  var NomeFileDest:String;
      Idx:Integer;
  begin
    for Idx:=1 to 5 do begin
      Application.ProcessMessages;
      Sleep(1000);
    end;

    Synchronize(@EmettiNomeFile);

    //Forzo la chiusura del Thread. Per qualche motivo, senza questa istruzione,
    //il thread sembrava sempre in esecuzione
    Terminate;
  end;

Praticamente ho solo spostato in basso la Synchronize e, questa non viene più eseguita. Se disattivo la processmessages invece funziona regolarmente.
Qui al lavoro ho Windows XP SP3.

Per me è il primo progarmma "serio" che sviluppo con i thread, quindi qualsiasi consiglio è benvenuto !!!

Ciao, Mario
Titolo: Re:Lavorare con i thread
Inserito da: Stilgar - Settembre 25, 2012, 11:09:41 am
Allora.
Il Syncronize serve per "stoppare" il thread secondario ed agganciarlo a quello principale. Se devi modificare il GUI è molto ultile ;)
Ti allego un pool scritto di fretta e furia.
Ti posso solo garantire che compila. L'idea è deleare a lui il fatto di gestire i thread.
Ho scoperto con mio sommo disappunto che la properties Terminated è stata nascosta ...  il pool introduce una classe Thread che assomiglia vagamente a quella Java.

Lo start e lo stop sono delegati al monitor ;)
Prova a buttarci un occhio, per farti un'idea :D
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Settembre 25, 2012, 11:36:17 am
Ho guardato, ma credo che non faccia al caso mio.
Il mio scopo è lanciare in parallelo un lavoro su tutti i files presenti in una directory. Siccome nella directory ci possono essere anche centinaia di files, faccio in modo di lanciare 10 conversioni contemporaneamente. man mano che una finisce, libera il relativo hread che può essere quindi occupato dal file successivo.
Se non ho capito male il tuo codice, con quello dovrei preparare prima tutti i thread e poi farli partire con StartPool. Se non è così allora non ci ho capito niente !!!!

In ogni caso, tornando alla domanda iniziale, a voi risulta che Application.ProcessMessages  non possa essere usata nella Execute di un thread perché la sua chiamata fa terminare il thread immediatamente?

Ciao, Mario
Titolo: Re:Lavorare con i thread
Inserito da: Stilgar - Settembre 25, 2012, 11:47:36 am
Mario, il codice non voleva essere una soluzione, ma un suggerimento su come gestire i thread.
Il "ProcessMessage" serve per prelevare dalla cosa dei messaggi (Windows almeno) e fare il dispatch ai controlli dell'applicazione stessa.
Se tu prelevi da un thread secondario i messaggi, potresti avere dei comportamenti anomali.
Il thread principale vedilo come un thread di "paint" e "read input".
Nei video giochi questi sono due thread distinti, per aumentare la fluidità delle immagini, ma in un gestionale non hai problemi di frame rate ;)
In linea di massima nulla ti vieta di forzare il process dei messaggi.
Leggevo qualche cosa sul fatto che è sconsigliato .... (Wiki di Lazarus, se ricordo bene).
Anzi, loro sconsigliavano proprio l'uso dei thread :D
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Settembre 28, 2012, 05:04:06 pm
Come mai hai detto al thread di siucidarsi al termine?

Mi è venuto in mente oggi facendo altre prove: ho notato che se non metto l'istruzione "Terminate;" alla fine della "Execute" e poi, in altre parti del programma, vado a testare "MyThread.Terminated", quest'ultima mi da dei risultati errati, dicendomi che dei thread non sono terminati anche se invece lo sono. Facendo come ho fatto io, invece, se testo "MyThread.Terminated" mi da sempre il risultato corretto.
Non so se è un bug di Lazarus, ma dalle prove che ho fatto ho notato questo.

Ciao, Mario
Titolo: Re:Lavorare con i thread
Inserito da: Stilgar - Settembre 28, 2012, 11:42:32 pm
Ciao Mario,
 allora non penso sia un problema del lazzarone o della libreria base.
Credo che il terminate (se controlli il codice puoi verificare da solo) non faccia altro che indicare FTerminate := true;
Codice: [Seleziona]
//estratto dal file classes.inc riga 78
function ThreadProc(ThreadObjPtr: Pointer): PtrInt;
  var
    FreeThread: Boolean;
    Thread: TThread absolute ThreadObjPtr;
  begin
    { if Suspend checks FSuspended before doing anything, make sure it }
    { knows we're currently not suspended (this flag may have been set }
    { to true if CreateSuspended was true)                             }
//    Thread.FSuspended:=false;
    // wait until AfterConstruction has been called, so we cannot
    // free ourselves before TThread.Create has finished
    // (since that one may check our VTM in case of $R+, and
    //  will call the AfterConstruction method in all cases)
//    Thread.Suspend;
    try
      { The thread may be already terminated at this point, e.g. if it was intially
        suspended, or if it wasn't ever scheduled for execution for whatever reason.
        So bypass user code if terminated. }
      if not Thread.Terminated then
        Thread.Execute;
    except
      Thread.FFatalException := TObject(AcquireExceptionObject);
    end;
    FreeThread := Thread.FFreeOnTerminate;
    Result := Thread.FReturnValue;
    Thread.FFinished := True;
    Thread.DoTerminate;
    if FreeThread then
      Thread.Free;
    EndThread(Result);
  end;
In effetti il DoTerminate di TThread non è proprio come me lo aspettavo :
Codice: [Seleziona]
//Riga 49
procedure TThread.DoTerminate;
begin
  if Assigned(FOnTerminate) then
    Synchronize(@CallOnTerminate);
end;
Questi thread non fanno altro che chiamare una callback quando terminano, ma non indicano da nessuna parte che sono finiti. Come se prevedessero (in fase di progettazione di comunicare con una sorta di controller esterno).
Come vedi impostano il FFinished e non il FTerminate.
Quindi mi sembra che sia il caso di indicare che è "terminated" a mano ....
Se c'è qualcuno che è in grado di verificare il codice Delphi per questa classe, mi toglierebbe un dubbio ... a naja mi sembrava impostasse il FTerminated ... del Finisched non ho proprio la minima alba.
PS:
  Ma sono l'unico che si mette a guardare il codice delle librerie? Sono così smanettone? :(
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Settembre 29, 2012, 09:07:53 am
  Ma sono l'unico che si mette a guardare il codice delle librerie? Sono così smanettone? :(

No, ogni tanto ci guardo anch'io, solo che il mio livello è basso basso e quando trovo qualcosa che non capisco ed ho poco tempo vado in fiducia !!!
Se invece ho tempo per fare prove, cerco di sbatterci la testa !!!

Ciao, Mario
Titolo: Re:Lavorare con i thread
Inserito da: Stilgar - Settembre 29, 2012, 07:20:28 pm
Vuol dire che non sono l'unico smanettone del forum :D
Bene. ;)
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Dicembre 23, 2012, 10:30:32 am
P.S. Qualcuno sa dirmi come valutare come impostare il n° massimo di thread contemporanei? Ho provato con 20 ed il PC sembra reggere, ma siccome il programma dovrà girare anche su altri PC più o meno potenti, volevo evitare di sovradimensionare tale numero.

Ciao a tutti,
vorrei riproporre la domanda qui sopra citata ... c'è una qualche regola da seguire quando si fanno girare più thread contemporaneamente, per stabilirne il numero massimo? Qualcosa in base alla memoria, al n° di core o altro?

Grazie in anticipo, Mario
Titolo: Re:Lavorare con i thread
Inserito da: Stilgar - Dicembre 23, 2012, 02:10:11 pm
Oddio, quando sganci un thread dovresti "fregartene" del numero massimo di questi attivi.
Devi delegare al Sistema operativo questo genere di rogne ... altrimenti dovresti tenere conto anche degli altri processi. Non lavorando in DOS ... dove avevi il controllo completo della macchina e non era multi process ... diventa una regola assurda quella che mettresti in piedi.
In generale prova a vederli come Workers ...
Di quanti ne hai bisogno veramente?
Un server web sgancia un thread (vedi apache che funziona decentemente) per ogni client che si connette. Se ci dovessimo fissare con un numero massimo di workers, non potresti andare oltre un certo numero di connessioni nello stesso momento. Server veramente limitare il numero di connessioni?
La regola che seguo io (in Java) è : cosa mi serve sincrono e cosa mi serve asincrono.
In questo modo evito di gestire con i thread i bottoni (... non ditemi che è una cagata.... lo so anche io ... ma spiegatelo voi ad un ingegnere fresco di laurea ... d'altra parte io sono solo perito industiale ...).
Tieni conto che un processo è un thread, quindi il numero minimo lo sai a priori ;) 1 :p
Il numero massimo è in base alle tue esigenze.
Al massimo puoi fare un programmino che faccia inchiodare il processore con un uso massivo di thread che non facciano IO (altrimenti li rendi sincroni sul disco).
Non so ... calcolo massiccio ... mi viene in mente il fattoriale per semplicità di implementazione. Vuoi far fare il calcolo del Pgreco ...
Lo trovo in esercizio accademico, non molto utile nella vita di tutti i pc ... ops giorni ;)

Stilgar
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Dicembre 23, 2012, 08:16:56 pm
Il dubbio mi è venuto per il tipo di programma che sto facendo. Praticamente, data in input il percorso di una directory, cerco tutti gli mp3 contenuti e li ricodifico lanciando un eseguibile esterno.
Se ad esempio la directory contiene 1000 mp3, mi sembrava assurdo lanciare 1000 thread di ricodifica contemporanei. Così li lancio 10 alla volta e, appena ne termina uno, lancio il successivo.


Ciao, Mario
Titolo: Re:Lavorare con i thread
Inserito da: Stilgar - Dicembre 23, 2012, 10:49:19 pm
Ok, hai diviso il numero di operaziononi potenzialmente ammazza PC in più thread.
Nulla di sbagliato nel tuo approccio, anzi. Uso intelligente dello strumento.
A questo posso (se permetti) aggiungere un consiglio, dare questa "dimensione" in mano all'utente. Aggiungere un grado di libertà.
In moltri spider web trovi la possbilità di mettere il numero di download contemporanei. (Alla fine sono thread... capiamoci).
Se il tuo programma dovesse girare con una macchina rapida, con dischi veloci, magari un 20 thread che convertono in parallelo non sarebbe male.
Ma sbattendo contro un disco USB, magari a 3600 giri, su USB 1.0, magari 10 thread sono tantini.
La mia era solo la solita considerazione da menagramo ;)

Stilgar
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Dicembre 24, 2012, 07:26:23 am
Ottima idea !!! Devo rivedere qualcosina nell'approccio, ma penso che lasciar scegliere il n° di thread all'utente sia fattibile.

Grazie ancora, Mario
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Febbraio 21, 2013, 06:23:14 pm
Ti allego un pool scritto di fretta e furia.
Ti posso solo garantire che compila. L'idea è deleare a lui il fatto di gestire i thread.
Ho scoperto con mio sommo disappunto che la properties Terminated è stata nascosta ...  il pool introduce una classe Thread che assomiglia vagamente a quella Java.

Lo start e lo stop sono delegati al monitor ;)
Prova a buttarci un occhio, per farti un'idea :D

Ciao, in queste sere avevo un po' di tempo e stavo riguardando il tuo post che ho quotato.
Facendo un po' di ricerche, ho scoperto per caso l'esistenza del componente "multithreadprocs" che si trova in "lazarus/components/multithreadprocs" che, da quel che ho capito, dovrebbe fare lo stesso lavoro che fa il pool che mi hai allegato.

Qualcuno di voi ha mai usato il "multithreadprocs"?

Ciao, Mario
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Marzo 10, 2013, 06:00:49 pm
Ciao a tutti,
vorrei riproporre la domanda qui sopra citata ... c'è una qualche regola da seguire quando si fanno girare più thread contemporaneamente, per stabilirne il numero massimo? Qualcosa in base alla memoria, al n° di core o altro?

Grazie in anticipo, Mario


Oggi avevo un po' di tempo, ed ho fatto un programma di prova.
I test li ho fatti sul mio PC che ha 4 processori, ognuno dei quali ha 2 core.
Il programma lancia la ricodifica di 25 brani mp3.
LA prima volta ho fatto in modo che lanciasse le ricodifiche una alla volta, poi 2 in parallelo, poi 3 in parallelo, e così via fino ad 8 in parallelo. Ogni prova l'ho ripetuta per 5 volte e l'ho fatta girare con il PC completamente dedicato a questo test, in modo da non avere "interferenze".
Questo è il risultato:
Codice: [Seleziona]
N° di processi in parallelo:  1    -  Tempo impiegato: 04 Minuti,  58 Secondi,  524 Millesimi
N° di processi in parallelo:  1    -  Tempo impiegato: 04 Minuti,  58 Secondi,  232 Millesimi
N° di processi in parallelo:  1    -  Tempo impiegato: 04 Minuti,  57 Secondi,  116 Millesimi
N° di processi in parallelo:  1    -  Tempo impiegato: 04 Minuti,  57 Secondi,  524 Millesimi
N° di processi in parallelo:  1    -  Tempo impiegato: 04 Minuti,  57 Secondi,  826 Millesimi
N° di processi in parallelo:  2    -  Tempo impiegato: 02 Minuti,  36 Secondi,  312 Millesimi
N° di processi in parallelo:  2    -  Tempo impiegato: 02 Minuti,  36 Secondi,  578 Millesimi
N° di processi in parallelo:  2    -  Tempo impiegato: 02 Minuti,  36 Secondi,  798 Millesimi
N° di processi in parallelo:  2    -  Tempo impiegato: 02 Minuti,  36 Secondi,  596 Millesimi
N° di processi in parallelo:  2    -  Tempo impiegato: 02 Minuti,  37 Secondi,  401 Millesimi
N° di processi in parallelo:  3    -  Tempo impiegato: 02 Minuti,  20 Secondi,  980 Millesimi
N° di processi in parallelo:  3    -  Tempo impiegato: 02 Minuti,  17 Secondi,  397 Millesimi
N° di processi in parallelo:  3    -  Tempo impiegato: 02 Minuti,  17 Secondi,  180 Millesimi
N° di processi in parallelo:  3    -  Tempo impiegato: 02 Minuti,  18 Secondi,  647 Millesimi
N° di processi in parallelo:  3    -  Tempo impiegato: 02 Minuti,  19 Secondi,  700 Millesimi
N° di processi in parallelo:  4    -  Tempo impiegato: 02 Minuti,  03 Secondi,  885 Millesimi
N° di processi in parallelo:  4    -  Tempo impiegato: 02 Minuti,  05 Secondi,  175 Millesimi
N° di processi in parallelo:  4    -  Tempo impiegato: 02 Minuti,  04 Secondi,  278 Millesimi
N° di processi in parallelo:  4    -  Tempo impiegato: 02 Minuti,  04 Secondi
N° di processi in parallelo:  4    -  Tempo impiegato: 02 Minuti,  04 Secondi,  119 Millesimi
N° di processi in parallelo:  5    -  Tempo impiegato: 02 Minuti,  03 Secondi,  859 Millesimi
N° di processi in parallelo:  5    -  Tempo impiegato: 02 Minuti,  03 Secondi,  208 Millesimi
N° di processi in parallelo:  5    -  Tempo impiegato: 02 Minuti,  04 Secondi,  753 Millesimi
N° di processi in parallelo:  5    -  Tempo impiegato: 02 Minuti,  04 Secondi,  946 Millesimi
N° di processi in parallelo:  5    -  Tempo impiegato: 02 Minuti,  02 Secondi,  560 Millesimi
N° di processi in parallelo:  6    -  Tempo impiegato: 02 Minuti,  03 Secondi,  999 Millesimi
N° di processi in parallelo:  6    -  Tempo impiegato: 02 Minuti,  04 Secondi,  768 Millesimi
N° di processi in parallelo:  6    -  Tempo impiegato: 02 Minuti,  03 Secondi,  663 Millesimi
N° di processi in parallelo:  6    -  Tempo impiegato: 02 Minuti,  04 Secondi,  220 Millesimi
N° di processi in parallelo:  6    -  Tempo impiegato: 02 Minuti,  05 Secondi,  486 Millesimi
N° di processi in parallelo:  7    -  Tempo impiegato: 02 Minuti,  02 Secondi,  739 Millesimi
N° di processi in parallelo:  7    -  Tempo impiegato: 02 Minuti,  03 Secondi,  209 Millesimi
N° di processi in parallelo:  7    -  Tempo impiegato: 02 Minuti,  02 Secondi,  989 Millesimi
N° di processi in parallelo:  7    -  Tempo impiegato: 02 Minuti,  02 Secondi,  726 Millesimi
N° di processi in parallelo:  7    -  Tempo impiegato: 02 Minuti,  03 Secondi,  070 Millesimi
N° di processi in parallelo:  8    -  Tempo impiegato: 02 Minuti,  04 Secondi,  747 Millesimi
N° di processi in parallelo:  8    -  Tempo impiegato: 02 Minuti,  05 Secondi,  210 Millesimi
N° di processi in parallelo:  8    -  Tempo impiegato: 02 Minuti,  04 Secondi,  562 Millesimi
N° di processi in parallelo:  8    -  Tempo impiegato: 02 Minuti,  04 Secondi,  128 Millesimi
N° di processi in parallelo:  8    -  Tempo impiegato: 02 Minuti,  04 Secondi,  374 Millesimi

Praticamente ci sono stati miglioramenti da 1 a 4 processi in parallelo. Da lì, fino ad arrivare ad 8 non è cambiato nulla, io invece mi aspettavo di avere miglioramenti fino ad 8 ...

Ciao, Mario
Titolo: Re:Lavorare con i thread
Inserito da: nomorelogic - Marzo 11, 2013, 09:48:43 am
spero di non dire delle boiate ma, a memoria, mi risulta che i processori dual core, per essere sfruttati in tutta la loro potenza di calcolo, devono eseguire algoritmi scritti per sfruttare l'elaborazione parallela (in modo da ovviare all'uso dei bus e cache che dovrebbero essere condivisi tra i 2 core).

il thread lanciato non necessariamente è stato scritto con un algoritmo che possa sfruttare l'elaborazione parallela e, in questo caso, le operazioni sono sempre sequenziali e non c'è modo di far passare parte del carico del lavoro al secondo core.

probabilmente se guardi i grafici di utilizzo dei core mentre lanci il tuo programma, dovresti vedere 8 core ma funzionanti solo la metà.
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Marzo 11, 2013, 01:22:20 pm
Stasera provo a guardarci con Windows. In linux in effetti, mi fa vedere i grafici di 4 core e non di 8 ...

Ciao, Mario
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Dicembre 19, 2018, 06:24:20 pm
Ciao,
mi collego a questo per non aprire una nuova discussione apposta ...
Ho un mega lapsus ....
In un programma, nel form principale valorizzo una TStringList con circa 2.000 righe.
Fatto questo, lancio una decina di thread in parallelo, ed ognuno di questi scorre quella TStringList per leggere gli elementi. La TStringList del form principale, viene quindi usata da tutti i thread, ma solo in lettura.

Questo può creare problemi? Mi conviene andare sul sicuro e duplicare la TStringList per passarla come parametro ad ogni Thread in modo che ognuno usi la propria?

Grazie in anticipo Mario
Titolo: Re:Lavorare con i thread
Inserito da: Stilgar - Dicembre 19, 2018, 06:57:27 pm
Solo lettura no.
Ma verifica di non modificare mai la lista finché in uso parallelo.
Stilgar
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Dicembre 19, 2018, 07:49:01 pm
Ok, grazie.
No, l'ho valorizzata tutta prima apposta, per poi usarla solo in lettura.

L'ho chiesto perché un paio di minuti prima di uscire dal lavoro, ho notato un comportamento "strano", ma non ho avuto il tempo di verificarne il motivo.
Poi, mentre tornavo a casa, ripensandoci, mi è venuto il dubbio che magari non solo la scrittura creava problemi, ma anche la lettura.

Comunque, meglio così, domani avrò una possibile causa in meno da verificare !!!

Grazie, Mario
Titolo: Re:Lavorare con i thread
Inserito da: Stilgar - Dicembre 19, 2018, 11:20:40 pm
Visto che lavori in parallelo, di solito è considerata una buona pratica generale  (non sapendo com'è organizzato il codice la menziono per completezza) semaforizzare gli accessi paralleli a risorse condivise. (L'esempio a scuola era la stampante ad aghi che mescolava caratteri e spazi di due processi in stampa... ma si parla di accesso diretto alla pnt con tutto l'onere dell'invio dei dati... ora credo sia vetusto come esempio 😂😂😂 anche se la vecchia panasonic mi ha dato molte soddisfazioni in stampa grafica giocando con il controllo dell'interlinea).
Una sezione critica è più che sufficiente per l'accesso alla memoria.
In alternativa potresti verificare se il thread n ha lo slot di esecuzione attivo e procedere alla lettura. È più spartano come controllo e meno sicuro.
Se hai problemi con la strada che stai seguendo ricordati le sezioni critiche. 😉

Stilgar
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Dicembre 20, 2018, 08:14:46 am
Perfetto, grazie, Mario
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Dicembre 20, 2018, 10:19:04 am
Scusate, ma ci sto girando intorno da mezz'ora ...
Sempre nello stesso programma di ieri, nel form principale ho una TMemo che uso come "log".

All'interno dei singoli thread ho questo codice:
Codice: [Seleziona]
  procedure TMyThread.ThreadAggiungiLog(WrkTestoLog: String);
  begin
    TestoLog:=WrkTestoLog;
    Synchronize(@SincronizzaLog);
  end;



  procedure TMyThread.SincronizzaLog;
  begin
    if VFPrimo then begin
      VFPrimo:=False;

      Form1.AggiungiLog('');
      Form1.AggiungiLog('     ' + 'Verificare il sorgente ' + ParmNomeFileNew);
    end;
    Form1.AggiungiLog(TestoLog);
  end;

Questo "metodo per emettere i log" l'ho già usato in altri programmi, e funziona correttamente.
Qui però i messaggi che aggiungo al log vengono mischiati tra di loro.

Ricordo male io o la "Synchronize" serve proprio per fermare tutti gli altri thread mentre si sta facendo qualche operazione particolare?

Grazie, Mario
Titolo: Re:Lavorare con i thread
Inserito da: Stilgar - Dicembre 20, 2018, 10:26:29 am
non è proprio così.Il thread fa le cose nella syncronize solo se gli altri non la stanno facendo.Quindi se il thread 1 ha scritto, libera la possibilità di scrivere al thread 2.Poi dipende da cosa ti aspetti e da cosa ottieni.:)
Titolo: Re:Lavorare con i thread
Inserito da: bonmario - Dicembre 20, 2018, 11:40:54 am
Avevi ragione: dal lanciavo più volte la procedura nel form principale per scrivere ogni singola riga di log.
Ho modificato il thread, per fare in modo di preparare il messaggio e poi lanciare una sola volta la procedura.
In questo modo, funziona correttamente.

Grazie ancora, Mario