pthread_cond_broadcast weckt nur 1 Thread



  • Hallo Leute,

    ich muss mal wieder ein Programm für die Uni schreiben. Es sollen mehrere Threads erstellt werden. 1 Thread soll Daten aus einer Datei einlesen, und in einem "string-array" speichern. Alle weiteren Threads sollen aus diesem Array lesen und damit weitere Funktionen anstoßen.
    Das Einlesen und Auslesen klappt ohne weiteres. Jedoch sollen alle Threads, die per pthread_cond_wait() im Wartezustand hängen, am Ende mit pthread_cond_broadcast() aufgeweckt werden, damit sie zur Beendigung kommen. Beim Aufruf der Funktion pthread_cond_broadcast() wird jedoch nur 1 Thread aufgeweckt, nicht alle 😞
    Hier mal ein paar Ausschnitte aus meinem Code:

    Verwendete Struktur

    typedef struct {
    	char *server[MAXELEMENTS];
    	long head, tail;
    	int full, empty, finished;
    	pthread_mutex_t *mut;
    	pthread_cond_t *notFull, *notEmpty, *isFinished;
    } queue;
    

    Erstellen der Threads und Aufwecken der wartenden Threads

    printf("MAIN: Creating Producer Thread Nr. %d\n", 1);
    pthread_create(&pro, &attr, producer, (void *)1);
    
    for (i = 1 ; i <= threads ; i++) {
    	printf("MAIN: Creating Consumer Thread Nr. %d\n", i);
    	pthread_create (&con, NULL, consumer, (void *)i);
    }
    
    while (fifo->finished == 0) {
    	pthread_mutex_lock(fifo->mut);
    
    	printf("MAIN: Waiting for end of reading file.\n");
    	pthread_cond_wait(fifo->isFinished, fifo->mut);
    	fifo->finished = 1;
    	sleep(1);
    	printf("Mum close all Threads.\n");
    	printf("Broadcast return value = %d\n", pthread_cond_broadcast(fifo->notEmpty));
    
    	pthread_mutex_unlock(fifo->mut);
    }
    

    Funktion zum Einlesen der Daten aus einer Textdatei

    void *producer (void *q)
    {
    	int who = (int) q;
    	int i;
    	int j;
    	char datei[] = "testsites.txt";
    	FILE *data;
    	char *zeile;
    
    	zeile = (char *) calloc (INPUTLENGTH+1, sizeof(char));
    
    	data = fopen(datei, "r");
    
    	while (fgets(zeile, INPUTLENGTH, data) != 0) {
    
    		pthread_mutex_lock(fifo->mut);
    
    		while (fifo->full) {
    			printf("PRODUCER %d: Queue full.\n", who);
    			pthread_cond_wait(fifo->notFull, fifo->mut);
    		}
    
    		queueAdd(fifo, zeile);
    
    		pthread_mutex_unlock(fifo->mut);
    		pthread_cond_signal(fifo->notEmpty);
    		usleep (100000 + j * 100000);
    		sleep(1);
    	}
    
    	fclose(data);
    
    	free(zeile);
    
            /* Senden des Signal für das Ende des Einlesens */
    	pthread_cond_signal(fifo->isFinished);
    
    	return (NULL);
    }
    

    Funktion zum Auslesen der Strings

    void *consumer (void *q)
    {
    	int who = (int) q;
    	int i;
    	char *d;
    	int j;
    
    	d = (char *) calloc (INPUTLENGTH+1, sizeof(char));
    
    	if (d == NULL) {
    		printf("ERROR: consumer() -> malloc failed.\n");
    		exit(1);
    	}
    
    	while (fifo->notEmpty) {
    
    		pthread_mutex_lock(fifo->mut);
    
    		while (fifo->empty && fifo->finished == 0) {
    			printf("CONSUMER %d: Queue empty.\n", who);
    			pthread_cond_wait(fifo->notEmpty, fifo->mut);
    			printf("CONSUMER %d got signal to continue.\n", who);
    		}
    
    		if (fifo->empty == 0 && fifo->finished == 0 ) {
    
    			queueDel (fifo, &d);
    			pthread_mutex_unlock(fifo->mut);
    			pthread_cond_signal(fifo->notFull);
    			printf("CONSUMER %d: received %s\n", who, d);
    		}
    
    		if (fifo->finished == 1) {
    			printf("Finish %d. thread.\n", who);
    			return (NULL);
    		}
    	}
    
    	free(d);
    	printf("--> Finish THREAD.\n");	
    	return (NULL);
    }
    

    Jemand eine Idee, was ich falsch mache?



  • zum ersten wirst zu probleme bekommen, wenn du mehr als einen producer hast, da alle die gleiche datei von anfang an auslesen. da musst du dir noch was überlegen. vorerst hast du aber nur einen producer, sodass alles so klappen sollte. zweitens fehlt dir ein "free(d);" im block von "if (fifo->finished == 1)". und drittens fehlt dir ein "pthread_mutex_unlock(fifo->mut);" im gleichen block. ich denke, dass das dein problem ist.



  • Besten Dank 🙂
    Bin mir zwar nicht ganz sicher, ob es daran lag, aber nun scheint es so zu laufen, wie es soll 🙂


Log in to reply