Multithread Programmierung

Perdan

Mitglied
Hallo,

ich muss ein Programm mit mehreren Threads programmieren. Leider habe ich damit noch keine Erfahrung.
Meine Frage ist jetzt bei welchen Variablen, Konstanten, Funktionen, usw. muss ich den Zugriff mit Semaphoren absichern?Wann verwendet man Shared Memory oder kann man auch einfach globale Variablen verwenden?

Wenn ich zum Beispiel ein Array habe wo alle Threads (nur lesend) zugreifen, muss ich da den Zugriff mit Semaphoren absichern oder nicht?

Vielen Dank für die Antworten.

MfG

Perdan
 
Hi!

ich muss ein Programm mit mehreren Threads programmieren. Leider habe ich damit noch keine Erfahrung.
C oder C++? UNIX, Windows oder portabel?

Meine Frage ist jetzt bei welchen Variablen, Konstanten, Funktionen, usw. muss ich den Zugriff mit Semaphoren absichern?Wann verwendet man Shared Memory oder kann man auch einfach globale Variablen verwenden?
Allgemein lässt sich sagen, dass Semaphoren immer dann gebraucht werden, wenn es mehreren Threads möglich ist Werte zu verändern - Konstanten brauchen also generell keinerlei Absicherung.
Funktionen nur dann, wenn Sie globale Änderungen vornehmen oder im eigenen Scope definierte, statische Variablen verändern. Wobei hier eher ein Mutex für die Variablen als für die Funktion anzuraten ist, sprich: Die Funktion sollte sich um die Absicherung kümmern, nicht der Aufrufende.
Shared Memory ist eher ein Mittel der IPC, weniger des Multithreadings.

Wenn ich zum Beispiel ein Array habe wo alle Threads (nur lesend) zugreifen, muss ich da den Zugriff mit Semaphoren absichern oder nicht?
Nein.

Gruß
Enum
 
Da hätte ich doch gleich noch eine weitere Frage zu diesem Thema:
Ich habe in einem Programm (eine Socketanwendung - epoll - um genau zu sein), an dem ich momentan bastle eine Liste (std::list), welche vom Accept-Thread mit Jobs gefüttert wird und die Worker-Threads diese Jobs dann abrufen und verarbeiten.
Ist dort auch eine Absicherung nötig, wenn der Accept-Thread die Daten hinten an die Liste hängt und die Wörker-Threads vorne die Daten "klauen"?
ich hatte es einmal ohne Mutex getestet und hatte keine Probleme. Das kann aber reiner Zufall gewesen sein.

@Perdan:
Für Windows empfehle ich dir MSDN für Unix/Linux einfach bisschen per Google suchen. Oft habe ich brauchebare Codeschnipsel gefunden, aus denen ich meine Infos hernehmen konnte. Ansonsten sind auch Man-Pages ganz praktisch, da sie hier und da Beispiele enthalten.
 
Ja, auf jeden Fall
Grundsätzlich: Sobald auch nur ein einziger Thread auf gemeinsamen Daten irgendwas ändert (dazu gehört auch das "wegnehmen" vorne), muss eine Absicherung her.

zB (ich nehm einmal an, du hast eine unidirektionale Liste):
Der Thread T1, der hinten Elemente hinzufügt, muss dafür grob gesagt:
1) Element im Speicher anlegen (und mit Daten füllen)
2) Nachschauen, ob an bestehende Elemente angehängt werden kann oder ob die Wurzel gesetzt werden muss
3) Die Adresse vom Neuen an der passenden Adresse eintragen
Thread T2 nimmt wieder Elemente vorne weg:
1) Liest und verarbeitet die Daten
2) Löscht das Objekt
3) Setzt den Wurzelpointer auf das neue erste

Angenommen, es gibt zurzeit genau 1 Element; beide Threads wollen ihre Arbeit machen und der Prozessor teilt sich das zufällig so auf:

T2 Liest einziges Element
T1 erzeugt zweites E
T1 sucht nach letztem Element zum Anhängen->Erstes Gefunden
T2 Löscht (noch) einziges Element
T1 schreibt Adresse vom Neuen Element dahin, wo das erste grad noch war (!)
T2 setzt Wurzel auf null, da das das letzte war

Daraus ergeben sich gleich zwei Probleme: Erstens ist das neue Element verloren gegangen, besetzt irgendwo ein Stückchen RAM und wird (von deinem Programm) nie mehr gelöscht
Zweitens (beim !) könnte eventuell von einem dritten Thread schon wieder Speicher reserviert worden sein, der überschrieben wird.

Auf jeden Fall absichern!

Gruß
 
OK, also so, wie ich es mir dachte und auch gemacht habe. Hätte ja sein können, dass std::list da nen internen Mechanismus hat oder so.

Danke.
 
Hallo zusammen,

erstmal vielen Dank für die Antworten. Es hat sehr geholfen. Leider habe ich noch eine Frage.

Ich eröffne einen Shared Memory mit der Größe einer Struktur. In dieser Struktur ist unter anderem ein Zeiger für Bilddaten. Diese Bilddaten sind erst zur Laufzeit bekannt (der speicher muss also dynamisch angelegt werden).

Die Frage ist nun: Der Zeiger auf den dynamischen Speicher liegt im Shared Memory, die Daten selber aber auf dem Heap oder?

Dazu habe ich noch eine Frage. Wenn ich 2 Threads habe, ist es dann möglich das der Heap des einen Threads Bereiche des anderen aus versehen überschreibt, oder sind die strikt getrennt (also automatisch ohne das ich mich darum kümmern muss)?

Danke für die Hilfe

MfG

Perdan
 
Zu Frage 1 kann ich dir leider nichts genaues sagen
Frage 2:Ja, zwischen Threads können Daten überschrieben werden.
Der Heap sollte aber eigentlich nur über Funktionen wie new/malloc etc verwaltet werden; solange du das einhälst, gibt es natürlich keine Überschneidungen.
Man muss halt darauf achten, nicht in Schleifen etc "versehentlich" über das Ende des Eigenen Speichers hinausläuft
 
Zuletzt bearbeitet:
Hi.

Zu Frage 1: Wenn du die Daten nicht im SharedMemory angelegt hast, werden diese ganz normal auf dem Heap abgelegt (und sind natürlich von anderen Prozessen aus nicht zugreifbar).
Frage 2:Ja, zwischen Threads können Daten überschrieben werden.
Der Heap sollte aber eigentlich nur über Funktionen wie new/malloc etc verwaltet werden; solange du das einhälst, gibt es natürlich keine Überschneidungen.
Das kommt aber darauf an, ob malloc/new thread-safe sind oder nicht - das ist implementierungsabhängig und nicht immer der Fall.

Von Threads gemeinsam genutzte Funktionen sollten thread-safe sein oder reentrant. Falls nicht muss man vor Nutzung der Funktionen Vorsichtsmaßnahmen ergreifen.

Gruß
 
Ok,

daraus ergeben sich die nächsten Fragen :).

Die Struktur mit den Bilddaten ist nicht von mir sondern von openCV und openCV regelt auch das einlesen das Bildes. Wie finde ich denn jetzt heraus ob die new /malloc sachen von openCV Threadsafe sind oder nicht?

MfG

Perdan
 
Die Struktur mit den Bilddaten ist nicht von mir sondern von openCV und openCV regelt auch das einlesen das Bildes. Wie finde ich denn jetzt heraus ob die new /malloc sachen von openCV Threadsafe sind oder nicht?
Das hat mit openCV wenig zu tun (außer die Bibliothek definiert ihre eigene Speicherverwaltung), sondern mit dem Compiler bzw. der verwendeten Laufzeitbibliothek.

Gruß
 

Neue Beiträge

Zurück