Metoda z klasy jako nowy wątek

0

witam,

jestem w trakcie pisania projektu i podczas jego pisania natrafiłem na taki problem: mam pewną klasę, w której jest metoda connect()

void connect();

w kodzie ją wykonuję i wszystko działa poprawnie tylko blokuje mi ta metoda cały program (a ma się wykonywać w czasie 90% czasu uruchomionego programu) i chciałem ją wykonać w oddzielnym wątku. Chciałem to zrobić tak:

pthread net_thread;
net = new Network(NET_SERVER);
pthread_create( &net_thread, NULL, net->connect, NULL);

no ale wywala błąd.... Próbowałem przerobić deklarację metody connect na analogiczną do tej ze strony http://www.gentoo.org/doc/pl/articles/l-posix1.xml (listening 1.2) i doszedłem do takiej deklaracji

void *connect(void *arg);

no ale kompilator mi wtedy zwraca taki błąd
error: argument of type ?void* (Network::)(void*)? does not match ?void* (*)(void*)?
i kilka innych. Czy ktoś mógłby mnie nakierować jak stworzyć ten wątek z metody w klasie?

0

Niech metoda wyjątku jest metodą statyczną klasy, która wywołuje connect na rzecz obiektu przekazanego jako ten voidowy wskaźnik. Musisz tylko podać wskaźnik na obiekt do pthread_create.

0

próbowałem napisać coś takiego
static void Network::*connect(void *net)
ale wywala mi wtedy taki błąd

network.cpp error: cannot declare pointer to ‘void’ member

w tej właśnie lini

0

Było.

0

tak, ale w WINAPI...
ja korzystam z biblioteki pthread

EDIT
próbowałem napisać coś w tamtym stylu i doszedłem do tego

void Network::Thread(Network *net)
{
	net->connect();
}

a potem
pthread_create( &net_thread, NULL, Network::Thread(net), NULL);
lecz niestety wywala mi kolejny błąd podczas kompilacji

error: cannot call member function ‘void Network::Thread(Network*)’ without object

0

tak, ale w WINAPI...

To nie ma znaczenia, bo idea ta sama. Trzeba ją tylko zrozumieć, a nie klepać bezmyślnie...

/* 'net' to wskaźnik oczywiście */
pthread_create(&net_thread, NULL, &Network::Thread, net);

p.s. według dokumentacji funkcja wątka powinna zwracać wskaźnik void*, a nie void.

0

napisałem, takie coś:

void *Network::Thread(Network *net)
{
	net->connect();
}

w mainie tak jak napisałeś i zwróciło mi błąd

error: cannot convert ‘void* (Network::)(Network)’ to ‘void* ()(void)’ for argument ‘3’ to ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* ()(void), void*)’

ps tak, net to wskaźnik do klasy
Network *net = new Network(NET_SERVER);

0

Network::Thread musi być statyczną metodą...

0

chyba coś znalazłem tutaj
http://lists.samba.org/archive/linux/2002-March/002522.html
jak wrócę z uczelni to to sprawdzę :)

0

dalej nic... Kod z linku wyżej nie działa. Zmieniłem go trochę, żeby mniej błędów wywalał podczas kompilowania na taki:

#include <pthread.h>

extern "C" void* StartPThread(void* arg);

class thread
{
   public:
      void run();   // creates a new thread and starts it

   private:
      pthread_t Thread;

      virtual void do_execute() = 0; // this is what gets executed by the 
                                     // override in a derived class
                                     // to execute the theaded code

   friend void* StartPThread(void*);
};

inline
void thread::run()
{

	int ECode = pthread_create(&Thread, NULL, StartPThread, 
                                  static_cast<void*>(this));
   if (ECode != 0)
   {
      //throw thread_error(ECode);
   }
}

// thread.cpp

extern "C"
void* StartPThread(void* arg)
{
   thread* MyThread = static_cast<thread*>(arg);
   return MyThread->do_execute();
}


int main()
{
	
	return 0;
}

ale wywala mi błąd

a.cpp: In function ‘void* StartPThread(void*)’:
a.cpp error: void value not ignored as it ought to be

wróciłem więc do mojego kodu i zmieniłem, żeby Network::Thread była statyczna

static void *Thread(Network *net);

ale nadal mam błąd:

error: initializing argument 3 of ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* ()(void), void*)’

w linijce

pthread_create(&net_thread, NULL, &Network::Thread, net);

czyli tam, gdzie dodaję wątek

0
static void* Thread(void *net);
0

ok, kompiluje się, ale.... nie wiem jak uruchomić tą metodę o którą mi chodzi, tzn ciało tej metody wygląda tak

void *Network::Thread(void *net)
{
	net->connect();
}

ale void to nie Network...

0

Ech, weź rzutuj po prostu ten pointer...

void *Network::Thread(void *net)
{
        Network *self = (Network *)net;

        self->connect();
}
0

wszystko działa :) dzięki

1 użytkowników online, w tym zalogowanych: 0, gości: 1