Threads, Stack



  • Guten Morgen,

    ich habe eine Frage zu Threads und was dabei mit dem Stack passiert. Hier erst mal ein Coding-Beispiel:

    struct Data
    {
    	char* nasty_pointer;
    };
    
    Data* data;
    
    void* run_child2(void* unused)
    {
    	sleep(3);
    
    	char* pointer = ((Data*)data)->nasty_pointer;
    	puts(pointer);
    	free(pointer);
    	return NULL;
    }
    
    void* run_child(void* unused)
    {
    	char* pointer = ((Data*)data)->nasty_pointer;
    	pointer = (char*) malloc(42 * sizeof(char));
    	strncpy(pointer, "lol", 4);
    	return NULL;
    }
    
    int main()
    {
    	data = (Data*) malloc(1*sizeof(Data));
    
    	pthread_t child_id, child_id2;
    	pthread_create(&child_id, NULL, run_child, NULL);
    	pthread_create(&child_id2, NULL, run_child2, NULL);
    
    	sleep(10);
    
    	pthread_join(child_id, NULL);
    	pthread_join(child_id2, NULL);
    	free(data);
    	return 0;
    }
    

    Das Programm allokiert mit Child 1 sofort Speicher und schreibt einen String rein. Child 2 soll nach 3 Sekunden den String lesen und den Speicher free()-en. Leider stürzt Child 2 schon bei der Ausgabe mit hässlichen segfaults ab (Zeiger sei uninitialisiert).

    Fragen:

    • Kann es sein, dass in dem Fall der Stack kopiert wurde und deshalb das malloc von Child1 ignoriert wurde?
    • Können (laufende) Threads dann überhaupt Daten (ohne "IPC") austauschen? oO
    • Gilt, dass nur der Thread, der einen Speicher allokiert hatte, auch das Recht hat, diesen zu free()-en?

    Ich würde mich sehr über Antworten freuen!

    Gruß,
    Johannes

    (@Mods: Bitte bei Möglichkeit nicht verschieben, die Implementierung ist hier zwar mit POSIX Threads, aber es geht um das allgemeine Verhalten von Threads. Danke.)



  • He ho du hast einfach vergessen in run_child
    den pointer wieder an deine data zu binden.

    data->_nasty_pointer = pointer; in run_child sollte genügen

    Zu deinen Fragen Threads Teilen sie alles. Und deine Frage sollte eher auf den Heap abzielen da dort Globale Variablen gespeichert werden.
    Der Heap wird auch geteilt. Bei Threads wird kein Speicherbereich kopiert sondern immer geteilt.



  • Hey Cefour,

    Danke für Deine Hilfe! 🙂 Jetzt gibt es keine Segfaults mehr. Darf ich bitte nochmal fragen, um ganz sicher zu gehen? In C müssen malloc()/free() wirklich nicht vom gleichen Thread ausgeführt werden?

    Meine Idee war nämlich, einen Threadpool für verschiedene, wiederkehrende Tasks zu verwenden. Und da könnte es ja durchaus passieren, dass ein Task zuerst von Thread 0 geschnappt wird, dort passiert ein malloc(), und später holt sich Thread 1 den Task und führt ein free() auf diesen Speicherbereich aus... Das geht also wirklich?

    Gruß,
    Johannes



  • Ja das geht. Aber du solltest tunlichst dich mit der syncronisation von Thread beschäftigen.
    Also Mutexe und so weiter, zwar ist die Sache mit sleep eine Lösung, aber die ist ziemlich dahin geklatscht und kann auch gewaltig schief gehen

    Gruß



  • Hey,

    danke für die Antwort! Klar, das sleep() war nur ne Notlösung. Und anstatt "Stack" war natürlich überall "Heap" gemeint 😉

    Gruß,
    Johannes


Anmelden zum Antworten