Newsgroup: it.comp.os.linux.development
Titolo: thread e C++

Salve a tutti
sto utilizzando dei thread all'interno delle classi c++.
la mia classe pippo ha 2 metodi pubblici, uno chiamato start e l'altro 
stop, che come viene suggerito dal nome, il fanno partire e fermano un 
thread.
Premetto che utilizzo un thread per classe e che all'interno della 
classe pippo esiste un metodo privato esegui
void * esegui (void)
nel metodo start ho fatto una chiamata
pthread_create (&ThreadId,NULL,&esegui,NULL);
il problema è che il gcc si incavola e mi dice
pippo.cpp: In member function `void pippo::start()':
pippo.cpp:50: warning: ISO C++ forbids taking the address of an 
unqualified non-static member function to form a pointer to member 
function.  Say `&pippo::esegui'
pippo.cpp:50: cannot convert `void*(pippo::*)(void*)' to 
`void*(*)(void*)' for argument `3' to `int pthread_create(pthread_t*, 
const pthread_attr_t*, void*(*)(void*), void*)'
non capisco perche non posso passare un metodo privato da far eseguire 
in parallelo. qualche suggerimento?
grazie mille
mirco

 in parallelo.
Le funzioni membro non sono funzioni ordinarie. Non è possibile utilizzare un
puntatore a una funzione membro senza disporre di un'instanza della classe. Per
questa ragione non è possibile (e non ha nemmeno senso) convertirlo in un
puntatore a funzione.
Dai un'occhiata a questo thread:
 
http://groups.google.it/groups?th=9693a134cfbe234c
Max

 la mia classe pippo ha 2 metodi pubblici, uno chiamato start e
Stò imparando che classi e thread non vanno molto d'accordo se non
stai attento.
Tieni conto che stò imparando anche io in questo momento.
Delle maniere che mi sono venute in mente per creare una classe
thread, ognuna ha i suoi problemi.
1) passare al constructor un puntatore a una funzione.
Un po' di problemi non banali mi vengono in mente... ma ho scoperto
guardando le librerie degli altri (CommonC++, ACE) che non è "the way
to go"
2) una classe Thread con una funzione run() virtual, da cui derivare
il tuo thread dove implementi una funzione run()
Il problema principale che mi viene in mente è la deallocazione delle
risorse e la parte dei ctor/dtor.
Quando fai un join... che succede a tutta la classe?
A questo punto devi ficcare nella tua classe thread una funzione join
che faccia il lavoro... oppure quando un thread si "suicida"? chi
raccoglie lo stato? e quando si detacha?
I dati della classe che scope hanno???
Non so quanto sia buono questo consiglio perchè ancora devo guardare
con più attenzione le librerie, non so quanto siano diffuse etc...
etc.. etc... ma dai un occhio a ACE e CommonC++
http://www.gnu.org/software/commoncpp/
http://www.cs.wustl.edu/~schmidt/ACE.html
Se qualcuno ha suggerimenti in merito a C++ e threads fa contento
anche me... dritte su libs già pronte incluse.
-- 
Ivan Sergio Borgonovo
mail.n...@webthatworks.it


grazie mille molto utile il tuo precedente post
ma ho scritto questo programmino
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <pthread.h>
#include <iostream.h>
#include <stdlib.h>
void* stampa (void * nonserve)
{
   for (int i=0;i<10;i++)
   {
   cout << "Hello, World!" << endl;
   }
   return NULL;
}
int main(int argc, char *argv[])
{
   cout << "inizio" << endl;
   pthread_t tid;
   pthread_create(&tid,NULL, &stampa, NULL);
   for (int k=0;k<100;k++)
   {
   cout << "ciao" << endl;
   }
//  pthread_join(tid,NULL);
   cout << "fine" << endl;
   return EXIT_SUCCESS;
}
innanzitutto quando esegui la pthread create mi va in crash :(
se tolgo il commento dalla pthread_join mi dice
/home/mirco/sviluppo/threadtest3/threadtest3/main.cpp:37: undefined 
reference to `pthread_join'
cosa sto sbagliando?

 mirco
goffredo
-- 
gpg key@ 
keyserver.linux.it
: Goffredo Baroncelli (ghigo)
<krei...@inwind.it.toglimi>
Key fingerprint = CE3C 7E01 6782 30A3 5B87  87C0 BB86 505C 6B2A CFF9

 anche me... dritte su libs già pronte incluse.
Boost [1] contiene molte librerie C++ con un ottimo design che
dovrebbero essere considerate durante lo sviluppo di un progetto.
Quindi oltre alla libreria per i thread [2] potrai trovare tante cose
molto utili.
Derfel
[1] 
http://www.boost.org/
[2] 
http://www.boost.org/libs/thread/doc/index.html
 [3]
[3] Per Debian: libboost-thread1.30.2 libboost-thread-dev

 cose molto utili.
Ero a conoscenza di boost consigliata in maniera generica già da
altri.
Mi era sfuggito avesse supporto anche per i thread.
Adesso quello che stò scrivendo lo ho cominciato in plain C.
Comunque vedo la scelta di una libreria C++osa strategica, non fosse
altro che poi bisogna imparare ad usarla e farlo per 3 librerie
richiede un sacco di tempo.
CommonC++ è blasonata in quanto GNU e poi è già disponibile nel
corredo delle maggiori distro.
ACE sembra altrettanto blasonata e per giunta usata sul campo ma non
appartiene al corredo delle maggiori distro.
boost++ ha dei nomi importanti tra gli autori, è piuttosto nominata...
Premetto che non è un'esigenza urgente però prima o poi mi troverò a
scegliere... commenti? paragoni? esperienze?

 
Come soluzione mi sembra molto elegante e permette di evitare extern C. 
a questo proposito
class Ttest {
public:
	Ttest();
	~Ttest();
   static void *  wrapper( void*p );
   void stop();
   void start();
};
premetto che poi metterò wrapper come privato,e che quini il file cpp mi 
risulta
/** Ttest:: */
static void * Ttest:: wrapper( void* p ){
}
il gcc mi dicet
test.cpp:25: cannot declare member function `static void*
Ttest::wrapper(void*)' to have static linkage
quindi sostanzialmente riotorno ad un tipo di errore originario del mio 
post :( ma come cavolo si fa ad eseguire un metodo privato di una classe 
in parallelo?
Grazie mille

 }
Togli 'static' nella definizione di 'Ttest::wrapper'. La keyword 'static'
all'esterno dalla dichiarazione di una classe ha un significato diverso.
Max