C++ Multithreading in Klassen

Squicky

Lt. Commander
Registriert
Sep. 2002
Beiträge
1.405
Hallo

Ich möchte Multithreading in C++ Klassen nutzen.
Habe http://openbook.galileocomputing.de/c_von_a_bis_z/026_c_paralleles_rechnen_004.htm#mja2eda8d735b0159acdc76284d6c9eb57 gelesen und folgendes versucht:


Code:
#include <iostream>
#include <pthread.h>
#include <stdio.h>

using namespace std;

class helper {
private:
    pthread_t thread;
    static void *start_help();
public:
    int id;
    void start();    
};

static void *helper::start_help() { 
    cout << "start_help :-) " << id << endl;
}

void helper::start() { 
    thread = pthread_create(& thread, NULL, & start_help, NULL); 
}

int main() {
    cout << "hallo main" << endl;

    helper x;
    x.id = 4711;
    x.start();

    return 0;
}


Leider funktioniert dies nicht. Laut meiner Internetsuche ist pthread_create eine C Funktion und funktioniert mit C++ Klassen nicht.

Aber es muss doch eine Multithreading Möglichkeit für Klassen in C++ geben.
Wie könnte man dieses kleine Beispiel richtig umsetzen?

P.S. Hier die Ausgabe:
Code:
"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Betrete Verzeichnis '/home/user/NetBeansProjects/CppApplication_1'
"/usr/bin/make"  -f nbproject/Makefile-Debug.mk dist/Debug/GNU-Linux-x86/cppapplication_1
make[2]: Betrete Verzeichnis '/home/user/NetBeansProjects/CppApplication_1'
mkdir -p build/Debug/GNU-Linux-x86
rm -f build/Debug/GNU-Linux-x86/main.o.d
g++ -pthread   -c -g -I/usr/include/c++/4.6.1 -MMD -MP -MF build/Debug/GNU-Linux-x86/main.o.d -o build/Debug/GNU-Linux-x86/main.o main.cpp
main.cpp:17:32: Fehler: Elementfunktion »static void* helper::start_help()« kann nicht deklariert werden, statische Bindung zu haben [-fpermissive]
main.cpp: In statischer Elementfunktion »static void* helper::start_help()«:
main.cpp:13:9: Fehler: ungültige Verwendung des Elementes »helper::id« in statischer Elementfunktion
main.cpp:18:34: Fehler: von dieser Stelle
main.cpp: In Elementfunktion »void helper::start()«:
main.cpp:22:63: Fehler: ungültige Umwandlung von »void (*)()« in »void* (*)(void*)« [-fpermissive]
/usr/include/pthread.h:225:12: Fehler:   Argument 3 von »int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)« wird initialisiert [-fpermissive]
make[2]: *** [build/Debug/GNU-Linux-x86/main.o] Fehler 1
make[2]: Verlasse Verzeichnis '/home/user/NetBeansProjects/CppApplication_1'
make[1]: *** [.build-conf] Fehler 2
make[1]: Verlasse Verzeichnis '/home/user/NetBeansProjects/CppApplication_1'
make: *** [.build-impl] Fehler 2

BUILD FEHLGESCHLAGEN. (Ausstiegswert 2, Zeit total: 374ms)


P.S.
 
Squicky schrieb:
Leider funktioniert dies nicht. Laut meiner Internetsuche ist pthread_create eine C Funktion und funktioniert mit C++ Klassen nicht.

Dann war deine Internetsuche Quark, denn es gibt keinen Grund, weshalb das nicht machbar sein sollte. Man muß nur syntaktisch fehlerfreies C++ schreiben. ;)

  1. Nimm bei der Definition (nicht bei der Deklaration, nur bei der Definition) von helper::start_help() das static weg.
  2. Gib deiner helper::start_help()-Methode einen Parameter vom Typ void*.
  3. In einer statischen Methode kannst du nicht auf nicht-statische Member zugreifen ... ist doch klar, oder?
  4. Der letzte Parameter von pthread_create() ist ein Pointer auf benutzerdefinierte Daten. Den kannst du "mißbrauchen", um einen Pointer auf eine Instanz deiner helper-Klasse zu übergeben (und zwar den this-Pointer). In deiner helper::start_help()-Methode bekommst du diesen Parameter dann wieder übergeben. Du castest dann diesen void-Pointer wieder zurück zu einem Pointer auf eine Instanz deiner helper-Klasse, und schon hast du eine Instanz, über die du auf dein id-Member zugreifen kannst.

P.S. Falls du das nicht nur tust, um was dabei zu lernen, würde ich dir empfehlen, die boost-Libaries zu benutzen ( http://www.boost.org/ ). Da gibt es auch ein Modul boost::thread, das das alles bereits kann. Wenn dein Compiler den C++11-Standard bereits unterstützt, ist std::thread sogar in der Standard-Bibliothek schon mit dabei.
 
Zuletzt bearbeitet:
Die Zeile
Code:
static void *start_help(void* par);
wurde durch
Code:
void *start_help(void* par);
ersetzt.

Habe das "<< id" auch entfernt. So dass Punkt vier später umgesetzt wird :-)

Aber auch mit diesen Änderung kommt es zu Fehler(n):
main.cpp:17:42: Fehler: Elementfunktion >>void* helper::start_help(Void*)<< kann nicht deklariert werden, statische Bindung zu haben [-fpermissive]
 
Hmpf, ich sagte doch, du sollst das static aus der Definition entfernen, nicht aus der Deklaration. Du hast es genau anders herum gemacht. ;)
 
Zurück
Oben