Newsgroup: it.comp.programmare.win32
Titolo: Parametri _beginthread()

Salve a tutti,
ho provato a lanciare in un thread separato una funzione senza parametri e
non
ho avuto problemi, ora vorrei richiamare questa funzione passandogli più
parametri
ma non ci riesco, qualcuno può aiutarmi?
Grazie.


Passagli i parametri utilizzando Ptr. Se definisci una struttura dati , per
esempio, puoi fare cosě.
struct dati
{
int Primo;
int Secondo;
char Stringa[100];
} MyData;
...
...
struct dati *Ptr=&MyData;
_beginthread( NomeFunzione, 0, (void *) Ptr  );
nella funzione ti ritrovi il puntatore all'area dati e pui fare
void NomeFunzione(void *Ptr)
{
    struct dati *p=(struct dati *)Ptr;
    Ptr->Primo=4;
...
...
}
Spero sia tutto chiaro...
***************************************
* 
http://www.edlsoftware.com
* 
emi...@edlsoftware.com
***************************************

 ha scritto nel messaggio
news:9ha10v$ln0$1...@fe1.cs.interbusiness.it...



Questo funziona sempre solo se MyData è una variabile globale!
Se mydata è allocata sullo stack rischi che il thread ci acceda quando 
questa è già stata sovrascritta da altri dati, nel caso in cui la funzione 
che ha creato il thread è già ritornata al chiamante e questo ha allocato 
nuovi dati sullo stack o richiamato altre funzioni. 
Se il thread legge i dati appena viene avviato e la funzione che lo ha 
creato esegue operazioni che durano molto più dello startup del thread 
tutto sembrerà funzionare correttamente, ma potrebbe generare crash (o, 
peggio, attivazioni del thread con parametri sballati) su PC 
particolarmente lenti,  particolarmente veloci (dipende da cosa viene 
eseguito dopo la beginthread e nella threadProc) o in casi particolari 
(errori che fanno ritornare la funzione "principale" immediatamente dopo la 
creazione del thread, ad esempio).
Per ovviare al problema, potresti allocare i dati dinamicamente (new o 
malloc) e rilasciarli dentro il thread (attenzione ai memory leaks!) o 
utilizzare un evento (passato al thread dentro MyData) che la threadProc 
provvederà a settare una volta terminata la lettura dei dati (in questo 
modo potrai lasciare i dati sullo stack, sicuro però di non sovrascriverli 
prima del necessario) oppure (solo se sei sicuro di avviare sempre un solo 
thread secondario) lasciare il buffer come variabile globale o data member 
di una classe allocata dinamicamente (questo è comunque uno spreco di 
memoria ed è giustificabile solo se il programma è davvero semplice e la 
struttura non occupa che pochi byte e non ti sembra il caso di implementare 
una delle due soluzioni precedenti).
-- 
Valter Minute
min...@inwind.it
 (the reply address of this message is invalid)

Avrei un' altra domanda,
ho realizzato programmino, per ora senza thread, che non è altro che il
cerca file di window.
Il problema però è che una volta che inizia a cercare il  file nel disco,
non ho + il controllo della applicazione finche non finisce la ricerca,
vorrei quindi utilizzare un thread per la ricerca.
void MyFunc(void *);
Da MyFunc non vedo le varie CEdit,CString ect.
Come devo dichiarare la mia funzione x poter avere oggetti delle suddette
classi?
Posso avere
int MyFunc(void *); invece di void MyFunc(void *);?
Grazie ancora.
"Valter Minute" <vmi...@REMOVEMEinwind.it> ha scritto nel messaggio
news:90CCAF242V...@212.110.0.170...


Puoi dirmi come e dove dovrei dichiarare la mia funzione da richiamare con
_beginthread
per poter utilizzare al suo interno tutte le funzioni che utilizzo
all'interno delle funzioni membro
della mia classe?
Dato che sono sicuro di essermi spiegato male ti dico quello che ho fatto,
ho dichiarato la mia funzione
    friend void myfunc(void*);
come public della mia classe, all'interno di mufunc però non riesco ad
utilizzare per esempio
la GetDlgItem, cosa che invece faccio all'interno di tutte le altre
funzioni.
Cosa devo fare?
Ciao e grazie.
"Valter Minute" <vmi...@REMOVEMEinwind.it> ha scritto nel messaggio
news:90CCAF242V...@212.110.0.170...


funzioni.
Il problema è che si tratta di una funzione esterna alla classe e che, se 
non ha un puntatore ad un'istanza della classe, non può richiamare funzioni 
non-statiche (questo dovrebbe anche essere l'errore che ti dà in fase di 
compilazione).
N.B. quando parli di "non riesco a utilizzare" specifica se si verifica un 
errore in fase di compilazione oppure a runtime e, in entrambi i casi, 
riporta il codice (spesso ritornato da GetLastError a runtime) o la 
descrizione dell'errore e magari un pezzetto (non più di 10 righe!) del 
codice incriminato.
Per ovviare al problema normalmente si dichiara una funzione statica 
all'interno della classe (meglio che usare friend, IMHO):
static void staticThreadFn(void* p);
la funzione si limita a fare il cast di p a un puntatore alla classe: 
MyClass* myp=(MyClass*)p;
e richiamare una versione non-statica della thread function (senza 
parametri)
myp->threadFn();
da cui puoi accedere a tutti i membri dell'istanza di classe.
ricordati di richiamare _beginthread passandogli un puntatore corretto:
se dentro una funzione della classe:
_beginthread(MyClass::staticThreadFn,0,this)
altrimenti
_beginthread(MyClass::staticThreadFn,0,myp)
Dai nomi di funzione che citi, mi pare che tu stia utilizzando MFC. 
Purtroppo (o per fortuna...) non ho mai utilizzato queste classi e quindi 
può darsi che qualcuno degli oggetti MFC abbia problemi se utilizzato 
contemporaneamente da thread diversi.
P.S. Quando rispondi evita di quotare il messaggio precedente alla fine del 
testo. Se devi rispondere ai vari punti rispondi alternando il testo 
quotato con le risposte (come ho fatto io) o elimina del tutto il testo 
quotato. Inoltre, se poni una domanda differente, è meglio iniziare un 
nuovo thread che potrebbe essere letto anche da chi ha ignorato questo.


Grazie mille.

Non arrabbiarti,
ho fatto come mi hai detto e funziona.
Ora però non ho più in effetti 2 thread separati, ma due funzioni, e quella
in cui ho utilizzato la _beginthread(MyClass::staticThreadFn,0,this) deve
aspettare che finisca quella lanciata dalla
MyClass::ThreadFn.
Grazie per l'enorme pazienza e per le risposte già date.
Ciao.

quella lanciata dalla MyClass::ThreadFn.
_beginthread torna appena viene attivato il secondo thread, non quando 
questo termina.
Se devi aspettare che il thread finisca immediatamente dopo che lo hai 
lanciato non hai bisogno di un thread.


Mi dispiace molto assillarti così ma sei l'unico che mi sta aiutando.
In questo programma ho una dialog principale che alla pressione di un
pulsante setta un timer
con un intervallo di 1 sec., ogni secondo lancio tramite la beginthread una
funzione dichiarata
fuori dalla classe void MyFunc(void*), all'interno della quale genero una
MessageBox(...),
in questo modo ho "sempre" il controllo della dialog principale dalla quale
posso fermare il timer.
Se invece lancio con la beginthread la funzione statica dichiarata nella mia
classe che a sua volta
richiama l' altra funzione che genera anche lei una MessageBox(...) io non
ho + il controllo della dialog principale finchè non chiudo tutte le
MessageBox(..) e quindi non riesco a fermare il timer.
Grazie ancora per la tua infinita pazienza.
Ciao.

: 

Credo che questo dipenda in qualche modo da MFC...
Probabilmente le MessageBox create da dentro una dialog hanno come parent 
la dialog stessa e quindi la disabilitano, rendendo in qualche modo inutile 
la gestione multithread.
Se invece utilizzi l'API MessageBox, ci deve essere qualcosa che mi 
sfugge...
Mi sfugge comunque l'utilità di un programma che genera una message box al 
secondo (se non per allenare l'utente all'uso del mouse...).


Il programma non ha alcuna utilità se non quella di permettermi di imparare
l'utilizzo
dei thread.
Ciao e grazie di tutto.
"Valter Minute" <vmi...@REMOVEMEinwind.it> ha scritto nel messaggio
news:90CE6DFCDV...@212.110.0.170...


Sono di nuovo qui,
avrei un'altra domanda.
Io ho questa funzione globale così dichiarata
void Prova(void*);
la richiamo poi all'interno di una funzione membro di una classe prima in
questo modo
Prova(NULL);
e poi
_beginthread(Prova,0,NULL);
La funzione è questa
void Prova(void* p)
{
     SetWindowText(GetActiveWindow(),"CIAO");
     SetWindowText(GetDlgItem(GetActiveWindow(),IDC_EDIT1),"CIAO");
     EnableWindow(GetDlgItem(GetActiveWindow(),IDC_EDIT1),FALSE);
}
La domanda è questa:
Perchè se la richiamo così Prova(NULL); svolge correttamente le istruzioni
e nell' altro caso non succede niente (non viene neanche segnalato alcun
errore) ?
Grazie e ciao.