2016-10-17 6 views
0

Dies ist eine abgespeckte Version von etwas Code, der perfekt als Single-Thread-Programm funktioniert. Ich versuche, es Multithread zu machen. Das Ziel besteht darin, eine globale Liste von Strukturen zu erstellen und in einer Schleife Speicherplatz für die Liste neu zuzuweisen und ihre Größe für jede Iteration der Schleife um eine Struktur zu erweitern. Ich erhalte den folgenden Fehler:C - Double Free Fehler mit Pthreads

Terminated due to signal: ABORT TRAP (6) 
doublefree(54652,0x70000020a000) malloc: *** error for object 
0x7fbc13403400: double free 

Wie erwähnt, funktioniert es, wenn die Anzahl der Threads eins ist. Ich nehme an, dass mehrere Threads versucht werden, den gleichen Speicher während Realloc() freizugeben. Aber sollte der Mutex das nicht verhindern? Der Zeiger für die Liste ist global, sollte also nicht jeder Thread den von den anderen geänderten Zeiger sehen? Ich sehe nicht, wie sich das von der Singlethread-Version unterscheidet. Wenn ich es immer und immer wieder durchführe, kann ich schließlich die korrekte Ausgabe erhalten, also gibt es eine Race Condition, die ich nicht sehe.

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 

typedef struct { 
    char key[512]; 
    int value; 
} KV_Pair; 
KV_Pair *pairList; 
int count = 0; 
void *doStuff(void *args); 
pthread_mutex_t mutex; 

int main(int argc, char *argv[]) { 
    pairList = malloc(sizeof(KV_Pair)); 
    pthread_t threads[4]; 
    int i; 
    for(i = 0; i < 4; i++) { 
     pthread_create(&(threads[i]), NULL, doStuff, NULL); } 
    for(i = 0; i < 4; i++) { 
     pthread_join(threads[i], NULL); } 
    free(pairList); 
} 
void *doStuff(void *args) { 
    while (1) { 
     pthread_mutex_lock(&mutex); 
     count++; 
     pairList = 
      realloc(pairList, sizeof(KV_Pair) * count); 
     pthread_mutex_unlock(&mutex); 
    } 
    pthread_exit(0); 
} 
+0

Der Compiler ein Register verwenden könnte Speichern Sie 'pairlist', bis die Funktion zurückkehrt. Versuchen Sie, 'pairList' als 'volatile KV_Pair * pairList;' zu deklarieren, um den Compiler zu zwingen, den neuen Wert sofort in den Speicher zu schreiben. –

+0

Was passiert, wenn 'realloc()' schließlich fehlschlägt und 'pairlist' auf' NULL' setzt? –

+0

Sind Sie sicher, dass Ihre abgespeckte Version, die Sie veröffentlicht haben, das dobule-freie Problem aufweist? – usr

Antwort

1

Sie haben Ihr Mutex zu initialisieren:

pthread_mutex_init(&mutex, NULL); 

So die Verriegelung nicht geschah. Sie würden dies gesehen haben, wenn Sie den Return-Code von geprüft hatten:

pthread_mutex_lock(&mutex); 

(22, ungültiges Argument, anstelle von 0, Erfolg), anstatt sie zu ignorieren ...

+0

Problem gelöst. Du bist ein Lebensretter. Ich kann nicht glauben, dass ich vergessen habe, dass ich initialisieren musste (ich habe sogar Mutexes ausgiebig benutzt)! – jmsul