Hi Robert 
Wenn ich mehrere Threads habe, die auf eine Member-Variable
eines Objekts lesend und schreibend zugreifen können, sollte
ich die dann per Semaphore synchronisieren […]
Jeder Thread hat seinen eigenen Stack. Daher musst du dich nur um Objekte im globalen Speicherbereich und solche auf dem Heap (new, delete) sorgen. Solange deine Klassenobjekte lokal sind, hast du also keine Probleme. Wichtig dabei ist, dass statische Member-Variablen im globalen Speicherbereich abgelegt werden.
Die nächste Frage ist, ob dein Objekt nur über Thread-Grenzen oder auch über Prozess-Grenzen hinweg geshared wird. Wird es nur innerhalb eines Prozesses geshared, reicht es, mit „critical sections“ zu arbeiten. Wenn du ein Objekt über Prozessgrenzen hinweg sharen möchtest, musst du mit „mutex“ arbeiten. Letzteres ist auf jeden Fall sicherer, deswegen gehe ich im Folgenden nur auf die Mutex-Methode näher ein. Am besten erzeugst du innerhalb deiner Klasse für jedes ihrer Objekte einen Mutex:
#include
class IamThreadSafe {
HANDLE m\_hMutex;
//Enter your data members here
public:
IamThreadSafe();
IdoSomething();
~IamThreadSafe();
//Enter your function members here
};
IamThreadSafe::IamThreadSafe()
{ m\_hMutex= CreateMutex(0,false,"myMutex");
assert (m\_hMutex!=0);
//Initialize your members here
}
void IamThreadSafe::IdoSomething()
{ WaitForSingleObject(m\_hMutex, INFINITE);
//Now a single thread has exclusive access
//Tell me what to do here
//Now other threads can access the resource again
ReleaseMutex (m\_hMutex);
}
IamThreadSafe::~IamThreadSafe()
{ m\_hMutex= 0;
}
Damit wird alles funktionieren
))
Und wie schauts aus wenn die Zugriffe nur lesend sind?
Wenn du wirklich nur Lesezugriffe hast, dann brauchst du dich nicht um das Threading zu kümmern. Die Probleme treten erst auf, sobald ein Thread eine Resource beschreiben will, die ein anderer gerade liest.
[…] oder reicht es die Member-Variable als volatile zu
deklarieren?
Oh nein, bloss nicht. „volatile“ ist das Gegenteil von „register“ und bedeutet nur, dass der Compiler die betreffende Variable immer direkt aus dem RAM holt. Stell dir vor, der Compiler würde z.B. einen Timerwert in einem Register halten. Dann kann es vorkommen, dass der Timer weiterspringt, der Compiler davon aber nichts mitkriegt. Mit einer volatile-Deklaration wird dies verhindert
))
cu Stefan.