PDA

Visualizza la versione completa : Thread C++ Builder


Kreator
11-10-2004, 18:30
Ciao raga.

Sto facendo un'applicazione all'interno della quale, sulla pressione di un tasto creo un thread per svolgere delle determinate funzioni su dei data-base.
A seconda di quanto e' grande il data-base, il tempo di esecuzione di questo thread può aumentare o diminuire.
Il mio problema sta nel fatto che mentre questo thread esegue queste determinate funzioni l'utente nel programma principale deve poter fare altre cose ... e non aspettare che il thread termini.
Attualmente quando eseguo il thread, il programma principale si blocca e devo aspettare la terminazione del thread.
Avete qualche consiglio ?
Se non lo posso fare con i Thread c'è un modo per sviluppare questa cosa ?

:dhò: :dhò:

alka
11-10-2004, 18:49
L'uso dei thread è la scelta giusta, ma apparentemente hai condiviso, più o meno volontariamente, qualche risorsa tra i due thread pertanto, nonostante siano separati, si arriva comunque alla condizione in cui uno deve attendere la fine dell'altro. Hai usato per caso metodi quali Synchronize? (fa parte della classe base dalla quale derivano tutti i thread, sia in Delphi che in C++Builder).

Ciao! :ciauz:

Kreator
12-10-2004, 14:54
no, asp, il thread e' uno solo.
Ovvero, il programma principale ha un tasto che quando lo premo mi istanzia il thread e me lo fa partire, il problema e' che quando parte il thread mi si congela il programma principale fino a quando il thread ha completato la sua esecuzione.

alka
12-10-2004, 15:01
Originariamente inviato da Kreator
no, asp, il thread e' uno solo.
Dalla tua spiegazione, i thread sono due: il primario (quello dell'applicazione) e il secondario (quello che esegue il lavoro alla pressione del pulsante).


Originariamente inviato da Kreator
Ovvero, il programma principale ha un tasto che quando lo premo mi istanzia il thread e me lo fa partire, il problema e' che quando parte il thread mi si congela il programma principale fino a quando il thread ha completato la sua esecuzione.
Come dicevo, questo significa che il secondo thread (quello attivato alla pressione del pulsante) fa riferimento - in modo sincronizzato - al thread primario (quello dell'applicazione) e rende bloccato quest'ultimo fino a quando il thread secondario non ha completato il suo lavoro.

Ad ogni modo, senza codice e ulteriori indicazioni, non è possibile dire di più, se non che posso garantirti il corretto funzionamento dei thread. :)

Ciao! :ciauz:

Kreator
12-10-2004, 15:06
ok, mi spiego meglio, spetta un attimo che ti faccio un bell'esempio

alka
12-10-2004, 15:09
Originariamente inviato da Kreator
ok, mi spiego meglio, spetta un attimo che ti faccio un bell'esempio
Scusa, ma potevi scrivere quando avevi questo esempio...
A cosa serve questo post inutile? (se non a richiamare l'attenzione...inutilmente, appunto?) :rollo:

Kreator
12-10-2004, 15:17
Praticamente l'esempio consiste nel fatto che vi e' una progress bar nel form principale, questa progress bar si incrementa ogni 50 millisecondi.
Le funzionalità di incremento sono demandate al thread, per il semplice fatto che nel frattempo che la barra si incrementa voglio svolgere altre operazioni.
Questo e' il mio main.



void __fastcall TForm1::AvviaFunzioniDBClick(TObject *Sender)
{
Thread = new TMyThread (false, ProgressBar1);
Thread->FreeOnTerminate = true;

}
//---------------------------------------------------------------------------


Questo invece e' il mio thread ...


__fastcall TMyThread::TMyThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
//---------------------------------------------------------------------------
__fastcall TMyThread::TMyThread (bool CreateSuspended, Comctrls::TProgressBar *temp) : TThread(CreateSuspended)
{
PBar = temp;
Priority = tpIdle;

// PBar e' stata dichiarata nel .h con: Comctrls::TProgressBar *PBar;


}//---------------------------------------------------------------------------
void __fastcall TMyThread::Execute()
{
Synchronize(MyFunction ());
}
//---------------------------------------------------------------------------
void __fastcall TMyThread::MyFunction ()
{
PBar->Position = 0;
for (int i=0;i<100;i++)
{
Sleep (50);
PBar->StepIt ();
}
}
//---------------------------------------------------------------------------

Premetto che con thread ho poca familiarità in quanto ho incominciato a studiarli da poco.

alka
12-10-2004, 15:30
Ok, deduco che tu non abbia letto attentamente la mia prima risposta, dato che c'era una esplicita richiesta sull'uso del metodo Synchronize alla quale non hai risposto. :)

Il metodo Synchronize permette di eseguire un metodo "sincronizzandolo" con il thread principale dell'applicazione; la chiamata a Synchronize deve essere fatta solo ed esclusivamente per quelle istruzioni che vanno sincronizzate con il thread principale, ad esempio per aggiornare una ProgressBar (come nel tuo caso) o altro ancora.

Se passi il metodo che occupa tempo e CPU alla Synchronize, il thread principale si fermerà fino a quando tale metodo non avrà terminato la sua esecuzione; limitati a chiamare la Synchronize solo nel punto esatto in cui devi aggiornare la ProgressBar o accedere a risorse (form, controlli, variabili) utilizzate dal thread primario.

Ciao! :ciauz:

Kreator
12-10-2004, 15:46
perfetto, ora funziona correttamente, mi sono creato un'altra funzione dentro il thread la quale non fa altro che incrementare la progress bar, e quella funzione la ho richiamata per mezzo della Synchronize, e ora funziona correttamente.

Grazie mille.

:ciauz:

Loading