Hilfe pthread_mutex will nicht



  • Hallo, zusammen, habe folgendes Progrämmchen mit viel Mühe zusammengeschustert. Leider schließt der Mutex andere Threads nicht aus. Was mach ich falsch?

    #include "aufgabe2.h"
    #include <pthread.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    
    #define ANZAHL_TEAMS 4
    #define ANZAHL_RUNDEN 10
    
    /* Diesen Code nicht modifizieren */
    struct Team teams[] = {
        {.name = "The Runtime Exceptions", .runtime = 1, .staffelstab = 1, .hand = 1},
        {.name = "Ueberholverbot", .runtime = 2, .staffelstab = 2, .hand = 2},
        {.name = "WiSo nur", .runtime = 5, .staffelstab = 3, .hand = 3},
        {.name = "Die laufenden Kopplungen", .runtime = 3, .staffelstab = 4, .hand = 4}
    };
    
    /* Sockel zum Halten des Staffelstabs */
    staffelstab_t sockel;
    
    /* Ab hier euren Code einfuegen */
    pthread_mutex_t lock;
    
    void* Runden(void *arg) {
    
        struct Team *f = (struct Team *) arg;
        int i = 0;
    
        while (i < 9) {
    
    	sleep(f->runtime);
    	pthread_mutex_lock(&lock);
    	printf("sockel vorher :%d  \n", sockel);
    	printf("%s  stellt den Staffelstab von Team %d auf den sockel.\n", f->name, f->staffelstab);
            sockel = f->hand;        
            printf("sockel hinterher:%d  \n", sockel);
    	printf("%s  nimmt jetzt Staffelstab von Team %d vom sockel.\n", f->name, sockel);
    	if (i > 0) {               
    	    sleep(1);
            }
            f->hand = sockel;        
            sockel = 0;
            printf("nachher sockel:%d  \n", sockel);
            pthread_mutex_unlock(&lock);        
            printf("%s  hat die Runde %d  abgeschlossen. Haben den Staffelstab von Team %d. Sollten aber %d in der Hand haben.\n", f->name, i + 2, f->hand, f->staffelstab);
            i++;
        }
        printf("%s  sind nun fertig. Haben den Staffelstab von Team %d. Sollten aber %d in der Hand haben.\n", f->name, f->hand, f->staffelstab);
    
        pthread_exit(NULL);
    }
    
    int main(void) {
        printf("*******************\n");
        int s = pthread_mutex_init(&lock, NULL);
    
            struct Team *f;
            int i = 0;
            while (i < 4) {
                f = &teams[i];
                int status;
                pthread_t laufen;
                status = pthread_create(&laufen, NULL, &Runden, f);
                if (status) {
                    printf("Problem bei pthead_create Teamname: %s \n", teams[i].name);
                }
                i++;
            }
            int t = pthread_mutex_destroy(&lock);
    
        pthread_exit(NULL);
    }
    //:::::Die Header-Datei:::::
    #ifndef AUFGABE2_H
    #define AUFGABE2_H
    
    #define LEER 0
    
    /* Diese Header-Datei wird nicht mit ins AsSESS uebertragen. 
     * Bitte keine Aenderungen an dieser Datei vornehmen.
     * /
    
    /* Typdefinition fuer den Staffelstab */
    typedef int staffelstab_t;
    
    /* Struktur fuer Teamrepraesentation. 
     * name: Name des Teams
     * runtime: Zeit fuer eine Runde
     * staffelstab: Staffelstab, der der Gruppe zugeordnet ist
     * hand: Aktuelle Staffelstab in der Hand des Laeufers. Zu Beginn hat der erste Laeufer des Teams
     *       den Staffelstab des Teams bereits in der Hand. 
     */
    struct Team {
        char* name;
        int runtime;
        staffelstab_t staffelstab;
        staffelstab_t hand;
    };
    
    #endif
    

    MfG



  • while (i < 4) {
                f = &teams[i];
                int status;
                pthread_t laufen;
                status = pthread_create(&laufen, NULL, &Runden, f);
                if (status) {
                    printf("Problem bei pthead_create Teamname: %s \n", teams[i].name);
                }
                i++;
            }
    

    Ich kenn mich mit den POSIX Threads zwar nicht aus, aber nachdem die Schleife durchgelaufen ist, ist pthread_t futsch. Vielleicht liegt es ja daran.



  • das ist es nicht, mutex will nicht....



  • saver schrieb:

    das ist es nicht, mutex will nicht....

    "Mutex will nicht" ist eine recht magere Fehlerbeschreibung. Was genau geht denn in die Hose?



  • ich will mit mutex sockel vor gleichzeitigem Zugriff schützen. Das funktioniert nicht. Die anderen threads greifen, unabhängig davon, ob den grad ein lock gegeben ist drauf zu.



  • saver schrieb:

    Die anderen threads greifen, unabhängig davon, ob den grad ein lock gegeben ist drauf zu.

    Und woran erkennst du das? Das mit dem lock/unlock sieht richtig aus. sockel hast du jedoch nirgendwo initialisiert. Wenn du kein C11 benutzt dürfte da ein magischer Wert drin stecken.

    Lies dir zusätzlich diesen Beitrag durch, da es hier wohl Kommunikationsprobleme gibt.



  • Nach Abarbeitung der Schleife in main() wird der Mutex zerstört, egal in welchem Zustand sich die erzeugten Threads befinden!



  • Sorry, wenn ich mich hier falsch verhalten habe. Danke für deinen höflichen Hinweis. Und ich bin wirklich dankbar für jede Hilfe.



  • Annehmender schrieb:

    sockel hast du jedoch nirgendwo initialisiert.

    Das ist eine globale Variable und die werden, wenn nichts anderes angegeben ist, mit 0 initialisiert.



  • Danke, habe die While-Schleife in der Main ersetzt:

    int main(void) {
        printf("  Start*******************\n");
        if (0 != pthread_mutex_init(&lock, NULL)) {
            printf("Problem bei pthread_mutex_init()!\n");
        } else {
            struct Team *f1;
    
            pthread_t team1;
            f1 = &teams[0];
            int status1;
            status1 = pthread_create(&team1, NULL, &Runden, f1);
            if (status1) {
                printf("Problem bei pthead_create Teamname: %s \n", f1->name);
            }
            struct Team *f2;
    
            pthread_t team2;
            f2 = &teams[1];
            int status2;
            status2 = pthread_create(&team2, NULL, &Runden, f2);
            if (status2) {
                printf("Problem bei pthead_create Teamname: %s \n", f2->name);
            }
            struct Team *f3;
    
            pthread_t team3;
            f3 = &teams[2];
            int status3;
            status3 = pthread_create(&team3, NULL, &Runden, f3);
            if (status3) {
                printf("Problem bei pthead_create Teamname: %s \n", f3->name);
            }
            struct Team *f4;
    
            pthread_t team4;
            f4 = &teams[3];
            int status4;
            status4 = pthread_create(&team4, NULL, &Runden, f4);
            if (status4) {
                printf("Problem bei pthread_create Teamname: %s \n", f4->name);
            }
            if (0 != pthread_mutex_destroy(&lock)) {
                printf("Problem bei pthread_mutex_destroy()!\n");
            }
        }
        pthread_exit(NULL);
    }
    

    ...sprich: erzeuge die Threads nun einfach manuell hintereinander. Bekomme folgende ausgabe:
    Start*******************
    'The Runtime Exceptions' sind nun mit Runde 2 fertig.
    'Ueberholverbot' sind nun mit Runde 2 fertig.
    'The Runtime Exceptions' nimmt jetzt Staffelstab von Team 'Ueberholverbot' in die Hand.
    'Die laufenden Kopplungen' sind nun mit Runde 2 fertig.
    'Ueberholverbot' nimmt jetzt Staffelstab von Team 'Die laufenden Kopplungen' in die Hand.
    'The Runtime Exceptions' sind nun mit Runde 4 fertig.
    'Die laufenden Kopplungen' nimmt jetzt Staffelstab von Team 'Ueberholverbot' in die Hand.
    ohoh.........wo ist der Staffelstab??? Team 'The Runtime Exceptions' wurde disqualifiziert!!! Hinsetzen!!!
    'WiSo nur' sind nun mit Runde 2 fertig.
    'Ueberholverbot' sind nun mit Runde 4 fertig.
    'WiSo nur' nimmt jetzt Staffelstab von Team 'Die laufenden Kopplungen' in die Hand.
    ohoh.........wo ist der Staffelstab??? Team 'Ueberholverbot' wurde disqualifiziert!!! Hinsetzen!!!
    'Die laufenden Kopplungen' sind nun mit Runde 4 fertig.
    'Die laufenden Kopplungen' nimmt jetzt Staffelstab von Team 'Ueberholverbot' in die Hand.
    'WiSo nur' sind nun mit Runde 4 fertig.
    'Die laufenden Kopplungen' sind nun mit Runde 6 fertig.
    'WiSo nur' nimmt jetzt Staffelstab von Team 'Ueberholverbot' in die Hand.
    ohoh.........wo ist der Staffelstab??? Team 'Die laufenden Kopplungen' wurde disqualifiziert!!! Hinsetzen!!!
    'WiSo nur' sind nun mit Runde 6 fertig.
    'WiSo nur' nimmt jetzt Staffelstab von Team 'Ueberholverbot' in die Hand.
    'WiSo nur' sind nun mit Runde 8 fertig.
    'WiSo nur' nimmt jetzt Staffelstab von Team 'Ueberholverbot' in die Hand.
    'WiSo nur' sind nun mit Runde 10 fertig.
    *********************'WiSo nur' sind nun fertig. Haben den Staffelstab von Team 'Ueberholverbot' in der Hand haben.
    zafer@zafer-EP3

    Schon in der dritten Zeile greift ein Thread auf den eigentlich geschützten bereich zu. Kann das an der while-Schleife in der Thread-Funktion liegen?



  • Bleib bei der Schleife und erstell außerhalb dieser das Array pthread_t thread[ANZAHL_TEAMS]. Nach der Schleife wartest du auf die Thread mit pthread_join. Daraufhin zerstörst du den Mutex.
    Das unlock im Thread musst du aus dem if-Block ziehen.



  • vielen Dank, klappt 😃 😃 😃 danke danke


Anmelden zum Antworten