Newsgroup: it.comp.programmare.win32
Titolo: thread

Salve a tutti.
Sto smanettando da poco con VC++ 6, e sto facendo a pugni con i
thread.
Volevo provare, didatticamente, a far interagire un thread con dei
campi del dlg. Semplificando ancora di piu', una cosa di questo tipo:
static void funzione_thread()             // (2)
{
  m_campo = "modifica effettuata";  // (1)
  UpdateData(FALSE);
}
void CProvathreadDlg::Onbottone() 
{
  AfxBeginThread(funzione_thread);             // (2)
}
(1) m_campo e' un edit sulla dlg CProvathreadDlg. Come faccio a
riferirmi a lui ? (idem per UpdateData)
(2) c'e' un modo per passare dei parametri alla funzione_thread ?
Es.
static void funzione_thread(int a, int b)             // (2)
{
  m_campo = a + b;
  UpdateData(FALSE);
}
Ho fatto un'altra prova riportata come esempio in un testo:
UINT ThreadProc(LPVOID param)
{
  ::MessageBox((HWND)param, "Thread attivato", "Thread", MB_OK);
  return 0;
}
void CTHREADView::OnStartthread() 
{
  HWND hWnd = GetSafeHwnd();
  AfxBeginThread(ThreadProc, hWnd, THREAD_PRIORITY_NORMAL);
}
Questo funziona. Una sostanziale differenza potrebbe essere che il mio
prg e' DDI mentre l'esempio e' SDI.
Sto andando in crisi mistica. E' frustrante quando, davanti ad un
argomento nuovo, ti insabbi nei concetti piu' stupidi...
Ciao e grazie.
PC


[...]
Credo che, prima di utilizzare i thread attraverso MFC ti convenga dare
un'occhiata alle API relative (CreateThread...). 
In generale un thread č collegato a una funzione che ha un argomento a
32bit (un long o un puntatore). Questo argomento di permette di passare
al thread una struttura o ancora meglio il puntatore a una classe. Non
puoi utilizzare una member function come thread function poiche ogni
member function ha un parametro "nascosto" (il puntatore this). E'
comunque possibile collegare un thread a un'istanza di una particolare
classe con questo "trucchetto": 
class ThreadClass
{
    	//questa funzione č static e puň essere passata alla
    	//CreateThread
    	static LRESULT CALLBACK staticThreadFunc(LPVOID* ptr)
    	{
    	    	return ((ThreadClass*)ptr)->threadFunc();
    	}
    	//basta implementare questa funzione per eseguire del codice
    	//che puň accedere a tutti i membri della classe in un thread
    	//separato
    	virtual LRESUL threadFunc()=0;
    	//funzione che avvia il thread nel modo piů semplice
    	//(probabilmente vorrai aggiungerci altri parametri)...
    	//P.S. non dimenticarti la CloseHandle sul valore di ritorno :-)
    	HANDLE start(DWORD* id)
    	{
    	    	return CreateThread(NULL,0,staticThreadFunc,this,0,id);
    	}
}
Tieni presente inoltre che il corretto funzionamento di un programma
multithread spesso dipende da una corretta sincronizzazione tra i vari
thread gestita tramite eventi,mutex,semafori,critical section... 
-- 
Valter Minute - 
min...@fortech.it
 (the reply address of this message is
invalid) --
Are you looking for a good freeware ScreenSaver? Try FOYD!
http://hotfiles.zdnet.com/cgi
-bin/texis/swlib/hotfiles/getit.bin?fcode=000PZ0 if you want, I can send
you the (free) C++ source code. 

un'occhiata alle API relative (CreateThread...). 
Hai ragione. Pensa che sto seguendo un testo che ha presentato i
thread come una cosa semplicissima, in 6-7 pagine e facendo
riferimento solo a AfxBeginThread senza, tra l'altro, spiegarne
completamente il funzionamento. 95 carte ! Bastano ?
Grazie per le dritte e approfitto della tua gentilezza per un altro
paio di cose:
1) Su questo famoso libro c'e' un esempio semplicissimo con
AfxBeginThread che funziona perfettamente al primo colpo sempre che si
sia creata un'applicazione SDI. Se porto questo esempio in
un'applicazione Dialog Based, in fase di compilazione mi viene detto
che nessuno dei 2 overload di AfxBeginThread riesce ad accettare il
tipo della funzione thread. C'e' un'effettiva differenza tra quello
che si puo' usare in una SDI ed in una Dialog Based ?
2) Ho seguito le tue dritte ma, lo ammetto, per inesperienza non
riesco ancora a muovermi. Sono troppo esigente se ti chiedo di perdere
2 minuti per sviluppare una "stronzatina" funzionante ed inviarmi il
tutto via mail ? Mi basterebbe: applicazione Dialog Based, sul dlg un
campo ed un bottone, alla pressione del bottone viene lanciato un
thread che scrive "pippo" nel campo del dlg e muore li.
3) Grazzzzie
Bye
PC

paio di cose:
[... domande sulle MFC...]
Mi spiace ma non utilizzo le MFC da parecchio tempo... :-)


Mi spiace ma non utilizzo le MFC da parecchio tempo... :-)
Uh !?!? Fammi capire. Non le usi perche' non programmi o perche' usi
altre alternatice ? In quest'ultimo caso, per curiosita', cosa usi e
perche' ?
Grazie per la pazienza.
Bye
PC

:

Solitamente sviluppo applicazioni che hanno un interfaccia utente molto 
limitata (qualche dialog di configurazione) e preferisco non appesantire il 
programma con un framework come MFC. 
Mi limito alle API di sistema.


 thread che scrive "pippo" nel campo del dlg e muore li.
La soluzione di minima, per una tipica applicazione MFC Dialog
Based, e.g. come quelle generate dal Wizard:
UINT thread_func(void* pparam)
{
    return ::SetWindowText(static_cast<HWND>(pparam), "Pippo");
}
void CMfc_thread_exampleDlg::OnRunThread()
{
    AfxBeginThread(thread_func,::GetDlgItem(m_hWnd,IDC_TEXT));
}
dove IDC_TEXT é l'id del "campo del dlg", e OnRunThread
la funzione membro da lanciare al clic sul bottone.
Difficile scendere sostanzialmente sotto 1 riga di codice ciascuna
per la funzione che lancia il thread, e per quella che gira entro il
thread... quanto al framework, per cose cosí minimali l'essenziale
é usarne uno che senza problemi "si faccia da parte" a richiesta
(notare l'uso di m_hWnd e delle API GetDlgItem e SetWindowText).
Alex