thread problem gemeinsamer speicherbereich
-
in deinen Beispiel gibst du in pthread_create keinen Wert, sondern einen Zeiger auf einen Wert. pthread_create ist asynchron, d.h. wenn die Funktion zurückkehrt, ist der Thread noch nicht gestartet, sondern das Starten läuft gerade im Hintergrund. gleichzeitig änderst du in der Schleife den Wert, dessen Adresse du übergeben hast
mögliche Lösung: nicht Adresse von Wert übergeben, sondern Wert
-
ahh ok stimmt.
vielen dank für die hilfe
-
tp = malloc(sizeof(*tp))
Wo ist dein free?
-
dd++ schrieb:
mögliche Lösung: nicht Adresse von Wert übergeben, sondern Wert
Da hast du nicht wirklich die Wahl, da das pthread-Interface alles über void* macht. Die müssen dann eben auf für den Thread eindeutige und konstante Parameter zeigen, wie bei meinem Beispiel. Du denkst gerade an C++-Threads, bei denen man beliebige Parameter übergeben kann (die dann intern sicherlich ganz was ähnliches machen, wie hier von Hand gemacht werden muss).
-
in diesem einfachen Beispiel kann man den int Parameter in einen void* casten und in der Threadmain den void* wieder in einen int. bei komplexeren Parametern kann man wie bei dir für n Threads n Parameter anlegen, oder man kann auch vor dem Starten den Parameter mit new/malloc anlegen und in der Threadmain mit delete/free wieder freigeben
-
ok wie ichs auch anstelle,ob mit oder ohne malloc, das ergebnis ist immer das gleiche. wie kann ich dem thread nur den wert übergeben?
-
xxmaxx schrieb:
ok wie ichs auch anstelle,ob mit oder ohne malloc, das ergebnis ist immer das gleiche. wie kann ich dem thread nur den wert übergeben?
Das wurde dir schon erklärt, inklusive vollständigem, funktionierendem Beispiel. Wenn es immer noch nicht funktioniert, dann wirst du wohl etwas bei der Umsetzung falsch gemacht haben. Das ist aber eine Frage deiner Umsetzung. Die Antwort, wie es geht, ist weiterhin die gleiche wie sie oben mehrfach gegeben wurde.
(Ich würde es aber auf keinen Fall so machen, wie dd++ sagt. Das ist unsauber.)
-
sorry. ich hab nicht bemerkt dass noch geantwortet wurde. hab ich erst jetzt
gesehen.
ok ich geb jetzt den speicher in den threads frei. scheint zu funktionieren.
nur versteh ich nicht ganz wieso. wenn das ganze so funktioniert wie dd++
zuvor erklärt hat.in deinen Beispiel gibst du in pthread_create keinen Wert, sondern einen Zeiger auf einen Wert. pthread_create ist asynchron, d.h. wenn die Funktion zurückkehrt, ist der Thread noch nicht gestartet, sondern das Starten läuft gerade im Hintergrund. gleichzeitig änderst du in der Schleife den Wert, dessen Adresse du übergeben hast
da würde es ja keinen unterschied machen wenn ich den speicher freigebe oder?
wenn der thread noch nicht gestartet ist und im hintergrund läuft und ich den wert in der schleife ändere dürfte das ganze doch trotzden nicht funktionieren. da ich den speicher ja erst "später" wieder freigebe.
-
Häh, welchen Speicher gibst du frei? Du sollst überhaupt gar nichts allokieren, geschweige denn freigeben! (knivil wollte dich darauf hinweisen, dass du, wenn du schon manuell Speicher verwaltest, es wenigstens richtig machen sollst.)
Guck dir nochmal mein Beispiel an.
da würde es ja keinen unterschied machen wenn ich den speicher freigebe oder?
wenn der thread noch nicht gestartet ist und im hintergrund läuft und ich den wert in der schleife ändere dürfte das ganze doch trotzden nicht funktionieren. da ich den speicher ja erst "später" wieder freigebe.Wie gut kannst du C? Ich habe den Eindruck du bist gerade ins tiefe Wasser gesprungen, obwohl noch Üben im Nichtschwimmerbecken angesagt ist. Was keine Schande ist, jeder muss erst einmal lernen.
Threads sind nicht ganz einfach. Du musst schon fit sein in Programmierung mit void*, um die Threads überhaupt nutzen zu können (im technischen Sinn) und natürlich im "parallelen" Denken, um etwas sinnvolles damit machen zu können. Das geht sicherlich beides nicht, wenn du noch Schwierigkeiten mit einfachen Ablaufplänen und er Vorstellung, was ein Objekt/Variable ist, hast.Die Erklärung, die ich und dd++ gegeben haben, wieso dein Programm nicht funktioniert, passt schon. Ich verstehe deinen Einwand überhaupt gar nicht. Er ist wirr.
-
wieso wirr? d++ hat doch geschrieben:
bei komplexeren Parametern kann man wie bei dir für n Threads n Parameter anlegen, oder man kann auch vor dem Starten den Parameter mit new/malloc anlegen und in der Threadmain mit delete/free wieder freigeben
gut hab ich dann wohl falsch verstanden. dein beispiel funktioniert ja. ich möchte halt nur nicht n parameter anlegen.
-
Die Threads darfst du natürlich schon dynamisch anlegen, wenn du willst. Aber du darfst ihnen nicht den Boden unter den Füßen wegziehen, während sie noch laufen! Ein einfaches Beispiel:
#include <pthread.h> #include <stdlib.h> #include <stdio.h> typedef struct { int arg1; double arg2; pthread_t thread; } thread_parameters; void* function(void* generic_args) { thread_parameters *args = generic_args; printf("Dies ist Thread %i mit Argument %f\n", args->arg1, args->arg2); return NULL; } int main() { unsigned num_threads; thread_parameters *threads; puts("Wie viele Threads?"); scanf("%u", &num_threads); if ((threads = malloc(num_threads * sizeof *threads))) { unsigned i; for (i = 0; i < num_threads; ++i) { threads[i].arg1 = i; threads[i].arg2 = i * 1.234; pthread_create(&threads[i].thread, NULL, function, threads + i); } for (i = 0; i < num_threads; ++i) { pthread_join(threads[i].thread, NULL); } } free (threads); return 0; }
Verbesserungswürdig ist noch die Erstellung, auf das Ende Warten und Zerstörung der Threads. Das könnte man schöner wegkapseln. Aber im Prinzip ist es das. Keine Speicherlöcher, kein verschwendeter Speicher, keine Race-Condition.
Könnte auch noch ein bisschen mehr Fehlerbehandlung vertragen (wie in Zeile 27), aber ich wollte das Beispiel nicht damit vollmüllen. Fehlerbehandlung in reinem C tendiert leider dazu, etwas unübersichtlich zu werden :p .
-
ok jz is alles klar.
danke