pthread_create



  • Ich versuche gerade ein kleinen Chat zu proggen, dabei will ich einen thread für listen und einen für send aufmachen, dummer weise klappt das mit der pthread_create funktion nicht so wie ich will, könnte mir wer nen beispiel source geben oder eine GENAUE (eine die über die man page hinausgeht !) erklärung der funktion ???
    THX
    ScoTch



  • Nu, ich versuch's ma:

    #include <pthread.h> 
    #include <stdio.h>  // printf
    #include <unistd.h> // sleep
    
    void* thread_function1(void*) { // Der Type ist wichtig: void* als Parameter und Rückgabe
      printf("Thread 1 gestartet\n");
      sleep(3); // 3 Sekunden warten
      printf("Thread 1 wird beendet\n");
    
      return NULL; // oder in C++: return 0;// Damit kann man Werte zurückgeben
    }
    
    int main() {
      pthread_t thread1; // Die Variable, in der der Tread 'gespeichert' wird
      // ein Initialisieren bedeutet zugleich das Erzeugen eines Threads:
      pthread_create( &thread1, NULL, thread_function1, NULL ); 
      sleep(1); // 1 Sekunde warten, damit der Thread seinen Text ausgibt
      printf("Hauptprogramm\n");
    
      // Schließlich sollte man noch auf den Prozess warten:
      pthread_join( thread1, NULL ); 
      printf("Ende\n");
    
      return 0;
    }
    

    Die 4 Parameter im einzelnen:

    1. zuerst einen Zeiger auf die Thread-Variable (vom Type pthread_t), die initialisiert werden soll
    2. Einen Zeiger auf eine Attribut-Struktur, falls der Thread besondere Eigenschaften besitzen soll. NULL bedeutet Standardeigenschaften
    3. Der Zeiger auf die Funktion.
    4. Wert, der der Thread-Funktion übergeben wird. In meinem Beispiel wird NULL übergeben, man kann auch etwas anderes nehmen - am besten einen anderen Zeiger:
    struct thread_args {
      int any_value;
      ... weitere Variablen
    };
    
    void* thread_function( void* data ) {
      thread_args* args = (thread_args*) data; // Parameter zum 'richtigen' Type zurückwandeln
      printf("%i\n", args->any_value); // den Wert ausgeben
      return NULL; // Dummy-Wert
    }
    int main() {
     ...
      thread_args args = {4711}; // Struktur erzeugen und ausfüllen
      pthread_create( &thread, NULL, thread_function, (void*) &args ); 
    // args übergeben. Der Cast ist nicht notwendig, wollte nur darauf hinweisen   :)
    }
    

    Ohne lange zu erklären, auf einen 'normalen' Thread sollte man warten, man kann ja sich notfalls mit einer globalen Variablen syncronisieren. Alternativ könnte man auch eine Spezial-Variable in der Struktur eintragen, wie 'bool thread_finished". Aber Syncronisieren führt jetzt etwas zu weit, notfalls nochmal nachfragen. Eine 2. Möglichkeit wäre, den Thread als "detatched" zu markieren, dann muss man nicht warten - man darf sogar nicht.
    Alle Thread-Funktionen geben einen int-Wert zurück. Ist der 0, hat alles geklappt, sonst wird dort der Fehlercode abgespeichert. Diese aufzuzählen, macht keine Sinn, darum der Verweis auf die man-Page und auf die Funktion "strerror".

    Das war nur eine sehr kurze Erklärung, bei genauen Problemen, wie schon erwähnt, einfach nachfragen.

    cu

    <edit von kingruedi>
    interessante Links:
    http://www-106.ibm.com/developerworks/linux/library/l-posix1.html
    http://www.humanfactor.com/pthreads/
    </edit>



  • Okay, soweit habe ich das jetzt, dummerweise kommt bei meinem Prog wie auch bei deinem Beispiel die fehlermeldung:
    undefine reference to 'pthread_create' !!!!!!
    Ich habe keine Ahnung was ich jetzt anstellen soll !
    Wer kann mir helfen ???
    THX ScoTch



  • Compileroption -lpthread angegeben?



  • Guten Abend zusammen,

    ich habe mich ja auch schon gemeldet wegen meinem Problem, dass ich mehrere Funktionen gleichzeitig ablaufen lassen will. Das sieht ja schon ganz gut aus da oben *g* nur bei mir ist das so:

    Ich habe ein While Schleife die in bestimmten Abständigen durchlaufen wird und dann immer diese eine Funktion aufrufen soll. Und jedes mal soll es ein neuer Prozess sein, d.h. die Funktion soll auch aufgerufen werden auch wenn die alte Funktion noch gar nicht fertig abgelaufen ist. Wie mach ich das denn dann? Ich kann doch bestimmt nur einmal diesen Thread erzeugen? Wie kann ich in einer while Schleife unbestimmt viele aufrufen?

    Miki



  • Wozu brauchst Du dazu Threads.

    Benutze fork()
    Dann kan es dir auch nicht passieren das dein Hauptprocess abstürzt da er eigentlich nur einen Process erstellt.



  • Hi,

    also das Prinzip sollte so aussehen:

    do
    {
    aufruf einer funktion
    }
    while bedingung

    Die while Schleife darf nicht anhalten, bis die Funktion beendet ist sondern muss fortgesetzt werden und wenn eine alte Funktion noch läuft, muss es möglich sein, dass die nächste aufgerufen wird. Das kann ich also mit fork umsetzen?

    Miki



  • Ja. Dazu ist fork da.



  • Wenn der Unterprozess 'unabhängig' vom Programm seine Arbeit verrichtet, dann sollte man forken. Der Unterprozess verhält sich wie eine Art Unterprogramm, man kann ihn Parameter mitgeben (lokale/globale Variablen) aber selbst liefert er keine Informationen zurück.
    Lies dir am besten nochmal Unix-Tom's Erläuterungen zu fork vs. Thread durch (letzter Link der anderen Frage) oder erkläre uns, was der Unterprozess tuen soll ...

    cu



  • Hi,

    also der Unterprozess, die Funktion wird mit einem Parameter aufgerufen und dann führt die Unterfunktion einige Aktionen aus, die auch länger dauern können und verändert global Variablen, auf die jeder weitere Aufruf dieser Unterfunktion auch zugreifen kann. Es soll also möglch sein, dass die Unterfunktion 10 mal läuft und alle auch an globalen Variablen arbeiten.

    Was mir nur nicht ganz klar ist:

    Ich habe mir ein Beispiel angeschaut in dem war der Code:

    child_pid = fork();
    switch(child_pid) 
    {
        case 0: // Das ist der Child-Prozess
            download_file();
            exit(0);
        case -1: // fork() ist fehlgeschlagen
            perror("fork");
            exit(1);
        default: // Das ist der Vater-Prozess
             // child_pid enthält die PID des Child-Prozesses
    }
    

    Das kann ich jetzt einfach in eine while schleife packen?

    Miki



  • Also das zugreifen auf Variablen des Mutterprozesses ist mittels fork nicht so einfach. Dafür sollte man die Interprocesskommuication können. (PIPE,Socket,etc)
    Wenn du das jedoch mit Threads machst mußt du Threads sehr gut können da der Zugriff auf Variablen des Hauptthreads syncronisiert werden muß.Ich mache das immer so das ich mir einen Deamonserver schreibe welcher mit Sockets arbeitet.
    Dh.: Eines Socket erstellen und diesen Asynch abhören. Somit kann man auch anderen Code ausführen. In diesem Process startest du mittels fork einen Childpr. welcher unabhängig vom Mutterprocess läuft.(2 Mal fork aufrufen)
    Wenn der Mutterprocess dann den Inhalt der Variablen des Childprocesses braucht dann einen Socketconnect zum Mutterprocess, welcher in diesem fall nicht mehr die Mutter des Child ist, aufbauen un ihm den Inhalt per Sockets senden. Danach den Childprocess schließen.


Anmelden zum Antworten