PDA

Visualizza la versione completa : [C++] Classe Thread e lancio di più thread indipendenti


emi81
09-05-2007, 12:10
Vorrei creare un classe thread che viene utilizzata nel main per lanciare piu thread indipendenti.

Al momento mi andrebbe bene che i tread stampino a video solo "Hello world" e basta.

praticamente vorrei avere una classe main in cui creo due thread, li faccio partire, e li stoppo.
e ovviamente una classe che descrive il comportamento del thread.


va benissimo qualsiasi aiuto, anche un link utile per un principiante, o magari 2 righe semplicissime di codice.

Sto lavorando in C++ con visual studio (windows) quinid posso utilizzare le apidi windows senza problemi.

Grazie a tutti!

bigmickey
09-05-2007, 12:29
Un esempio che modificai tempo fa.. nn ricordo da dove.


#include <windows.h>
#include <stdio.h>

long WINAPI Thread1(long lParam);
long WINAPI Thread2(long lParam);
long WINAPI Thread3(long lParam);


int main(void)
{
HANDLE hThread[3];
DWORD dwID[3];
DWORD dwRetVal = 0;



printf("Ciao dal main\n");


//release the threads. Remember, ThreadOne is our main thread
hThread[0] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Thread 1,NULL,0,&dwID[0]);
hThread[1] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Thread 2,NULL,0,&dwID[1]);
hThread[2] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Thread 3,NULL,0,&dwID[2]);


Sleep(1000);


//close handles
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
CloseHandle(hThread[2]);


system("pause");

return 0;
}

long WINAPI Thread1(long lParam)
{
printf("Ciao dal Thread 1\n");
return 0;
}

long WINAPI Thread2(long lParam)
{
printf("Ciao dal Thread 2\n");
return 0;
}

long WINAPI Thread3(long lParam)
{
printf("Ciao dal Thread 3\n");
return 0;
}

bigmickey
09-05-2007, 12:49
O anche qui ( http://www.codeproject.com/threads/Threads_1.asp)

emi81
09-05-2007, 15:43
ok, cosi funziona. solo che mi trovo ad avere due problemi :

1) ho creato due thread che dovrebbero fare la stessa cosa (un loop con delle stampe) ma in competizione, ma invece me ne parte uno solo, il secondo che lancio non fa niente. non stampa mai a video.


2) il main finisce prima che i threads che ho laciato finiscano la loro esecuzione.
ho sisolto il problema mettendo una Sleep() ma c'è un modo più bello per risolvere questo problema? anche perchè il tempo d'esecuzione varia ogni volta dai parametri e non posso ogni volta cambiare il tempo all'interno della Sleep.


Grazie!

bigmickey
09-05-2007, 16:17
Per quanto riguarda la prima dovresti postare il codice.

Per quanto riguarda la seconda, in effetti lo Sleep non è molto elegante,
dovresti usare le funzioni WaitForSingleObject o WaitForMultipleObjects.

Es. Aspetta 1 secondo (piu del tempo che serve al Thread1)



WaitForSingleObject( hThread1, 1000);


Per fare le cose in maniera poiù precisa:
con questa riga al posto della Sleep (nel codice che ho postato)
il main aspetta che i 3 thread siano conclusi prima di procedere.



WaitForMultipleObjects( 3 , hThread , TRUE, INFINITE);

emi81
11-05-2007, 12:06
il primo problema dipende dal fatto che non gestivo i semafori sulle variabili.
e quindi non c'era sincornia.


per quando riguarda il secondo punto, se ho capito dovrei scrivere cosi :





void Thread::start(){

hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Thread Executer,NULL,0,&dwID);

(void)WaitForSingleObject( hThread, 5000);

printf("CIAO\n");

return;
}


In questa maniera quando il mio thread a finito di eseguire aspetta 5 secondi e poi stampa a video CIAO. giusto?

solo che in reatà stampa subito dopo, e non dopo 5 secondi..

sicuramente rallenta , ma non mi sembra 5 secondi.

ho messo anche come valore 5000000 ma non sta fermo cosi tanto..me ne sarei accorto..

bigmickey
11-05-2007, 12:21
No, la WaitForSingleObject va inserita nel main.

La funzione aspetta massimo 5 secondi che il thread sia concluso,
la logica è che il main così controlla che il thread abbia finito il suo compito,
per poi "cancellarlo" definitivamente chiudendo l' handle con CloseHandle(handle);

emi81
11-05-2007, 12:25
ah, ok.
perfetto!


quando chiamo

hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Thread Executer,NULL,0,&dwID);

alla funzione ThreadExecuter posso passargli un parametro aggiuntivo?
perchè vorrei passargli un intero..

bigmickey
11-05-2007, 12:34
E' il quarto parametro.



HANDLE WINAPI CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);



Per maggiori dettagli vedi qui (http://msdn2.microsoft.com/en-us/library/ms682453.aspx)

emi81
11-05-2007, 14:22
ok, io chiamo il tread in questo modo :



int id = 3;
hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Thread Executer,&id,0,&dwID);


ora all'interno della mia funzione ThreadExecuter come faccio ad utilizzare il dato id ?

grazie :) :)

Loading