Parameterübergabe bei worker-Thread funktioniert nicht richtig



  • Hallo,
    ich habe eine Frage. Lerne Threads und ich bin ein bisschen am Rumexperementieren. Das Prorgamm, das ich hier poste, ist nur für Übungszwecke geschreieben worden und das könnte man viel effektiver schreiben(struct messages könnte z.B. man ersetzen, etc).
    In struct messages m wird m.i in einer for-Schleife gesetzt(0-9).

    for(int i=0; i<MAX; i++)
        {
            m.i=i;
            pthread_create(&threads[i],NULL, &worker, &m);
        }
    

    Allerdings wird bei der Ausgabe

     printf(m->read, m->i, pthread_self(), count);
     count++;
     printf(m->write, m->i, pthread_self(), count);
    

    immer eine 9 ausgegeben:
    message is 9, thread id = 317294336 , read the counter 0
    message is 9, thread id = 317294336 , modified the counter to 1
    message is 9, thread id = 308901632 , read the counter 1
    ...
    Kann mir jemand erklären warum?

    #define NDEBUG
    #include <stdio.h>
    #include <pthread.h>
    
    typedef struct messages messages;
    struct messages
    {
        char read[255];
        char write[255];
        int i;
    };
    
    int count=0;
    pthread_mutex_t count_mutex=PTHREAD_MUTEX_INITIALIZER;
    
    void* worker(void *pointer )
    {
        messages *m=(messages *) pointer;
        pthread_mutex_lock(&count_mutex);
        printf(m->read, m->i, pthread_self(), count);
        count++;
        printf(m->write, m->i, pthread_self(), count);
        pthread_mutex_unlock(&count_mutex);
    }
    
    int main()
    {
    
        messages m;
        strcpy(m.read,"message id is %d, thread id = %u , read the counter %d\n");
        strcpy(m.write,"message id is %d, thread id = %u , modified the counter to %d\n");
    
        const int MAX=10;
    
        pthread_t threads[MAX];
        for(int i=0; i<MAX; i++)
        {
            m.i=i;
            pthread_create(&threads[i],NULL, &worker, &m);
        }
    
        for(int i=0; i<MAX; i++)
        {
            pthread_join(threads[i],NULL);
            pthread_exit(&threads[i]);
        }
    
        return 0;
    }
    


  • Ist doch immer das gleich m, was willst du also?



  • Das ist ein typischer Multithreading-Pitfall, denn du übergibst an alle Threads die gleiche Adresse &m und veränderst aber dessen Inhalt.
    Die Ausgabe ist dann zufällig, je nachdem wann ein Threadwechsel stattfand (bei dir ist erst der Hauptthread komplett durchgelaufen, bevor die einzelnen Neben-Threads zum Zuge kamen und dann hat m.i den letzten Schleifenwert 9).

    Du müßtest entweder direkt i als Thread-Parameter übergeben oder jeweils eine eigene Message-Struktur (z.B. ein passendes Array dafür anlegen).



  • OK. Danke. Ich habe es mit einem Array gelöst. Jetzt klappt es.


Anmelden zum Antworten