threads und externe variablen
-
beginner31231 schrieb:
Habe mich ein wenig eingelesen und benutze eine critical section.
Habe auch volatile probiert aber beides kam zu keiner lösung.volatile ist Blödsinn hier. Ein(e) Mutex/CriticalSection ist vernünftig und funktioniert auch bei richtiger Anwendung.
beginner31231 schrieb:
Kann es da trotzdem noch probleme geben ? wenn ja welche ? Weil naja, es klappt eigentlich das nebenbei sachen eingefügt bzw gelöscht werden nur innerhalb des threads scheint die funktion das nicht mizukriegen.
Dann hast Du wohl etwas falsch gemacht.
Ich denke, Du solltest Dich "noch mehr einlesen" in die Materie.
Gruß,
SP
-
-
Athar schrieb:
Sebastian Pizer schrieb:
volatile ist Blödsinn hier.
Wie kommst du darauf?
siehe Link!
-
Sebastian Pizer schrieb:
siehe Link!
... und was willst du damit sagen? Da wird der Sinn von volatile beschrieben.
Wenn er auf die Veränderungen irgendwelcher Flags von außen wartet, muss er es hier höchstwahrscheinlich einsetzen. Um darüber eine Aussage treffen zu können, müsste man aber erstmal Code sehen.
-
Athar schrieb:
...irgendwelcher Flags von außen wartet, muss er es hier höchstwahrscheinlich einsetzen.
Was für "Flags von außen"? Ich gehe nicht davon aus, dass der OP Gerätetreiber programmieren will.
Entweder wird der Zugriff auf ein gemeinsames "Objekt" über einen Mutex synchronisiert (ist am einfachsten und weniger fehleranfällig), oder mit so etwas wie spinlocks + memory barrier -- lezteres erfordert aber atomare lese/schreib/austausch-Operationen, die
volatile(aus C und C++) nicht garantiert. Außerdem ist das eine ziemliche low-level Frickelei, welche man nur Experten überlassen sollte. Ich zähle mich übrigens nicht zu dieser Experten-Gruppe.Gruß,
SP
-
Naja das was ich mache ist, das vor der ersten benutzung einmal
InitializeCriticalSection aufgerufen wird, und dann vor jedem
zugriff auf den Vector EnterCriticalSection, und danach LeaveCriticalSection
calle. Hab ich da irgendwas verpasst ? :>
Mit volatile werd ichs nochmal probieren ^^
-
edit:
Das Problem ist nicht die Bool Variable.bool funktion(int id) { if(!initalized) { InitializeCriticalSection(&crit); initalized = true; } vector<example>::iterator it; EnterCriticalSection(&crit); it = structvector.begin(); while(it != structvector.end()) { if (it->id == id) { LeaveCriticalSection(&crit); return true; } else it++; } LeaveCriticalSection(&crit); return false; }So in etwa sieht die checkfunktion aus. Mach ich da irgendwas falsch ?
Da sieht man auch direkt wie ich die Critical Section verwende halt vor jedem
zugriff auf den Vector.
Die Schleife die das testet hat auch einen Sleep und testet nicht durchgehend.
ca so:while(boolvar) { Sleep(2000); boolvar = function(struct->id); }Wenn daran irgendwas falsch ist, wäre es nett mehr zu sagen
was ich falsch mache und wieso das falsch ist. Vielen dank
das ihr euch solche Mühe gebt
-
beginner31231 schrieb:
Mach ich da irgendwas falsch ?
Ja, denn die Initialisierung von crit erzeugt eine race condition, z.B.
// Thread 1 | Thread 2 if(!initalized) | if(!initalized) { | { InitializeCriticalSection(&crit); | initalized = true; | } | vector<example>::iterator it; | EnterCriticalSection(&crit); | | InitializeCriticalSection(&crit); | initalized = true; | } | vector<example>::iterator it; | EnterCriticalSection(&crit); // upsStatements, die in der gleichen Zeile stehen, stelle man sich als gleichzeitig ausgeführt vor.
Das Synchronisationsobjekt muss natürlich initialisiert worden sein, bevor mehrere Threads versuchen können, dieses zur Synchronisation zu verwenden. Zweckmäßigerweise macht man das also gleich bei der Erzeugung des zu schützenden vector.
Die Benutzung von RAII ist zu empfehlen.
-
Danke für die Informationen. Nunja, zu der Sache gleich bei der Erzeugung.
Ich habe den Vector nicht in dem mainprogramm sondern in einer anderen
cpp datei. Das heißt ich müsste den vector schon im main Programm erzeugen
und dann in der anderen cpp als extern angeben ?
Sprich ich müsste das im main Programm ca so machen -->CRITICAL_SECTION crit; InitializeCriticalSection(&crit); vector<example>vectorname;und in der anderen cpp dann halt
extern vector<example>vectorname;und wie vorher dann enter bzw leave benutzen nur
das initialize natürlich rausnehmen dann ?
Bei der erzeugung müsste ich jetzt nicht EnterCriticalSection benutzen ?!
Vielen dank nochmal für die Hilfe.
-
beginner31231 schrieb:
Danke für die Informationen. Nunja, zu der Sache gleich bei der Erzeugung.
Ich habe den Vector nicht in dem mainprogramm sondern in einer anderen
cpp datei. Das heißt ich müsste den vector schon im main Programm erzeugen
und dann in der anderen cpp als extern angeben ?
Sprich ich müsste das im main Programm ca so machen -->CRITICAL_SECTION crit; InitializeCriticalSection(&crit); vector<example>vectorname;und in der anderen cpp dann halt
extern vector<example>vectorname;und wie vorher dann enter bzw leave benutzen nur
das initialize natürlich rausnehmen dann ?
Bei der erzeugung müsste ich jetzt nicht EnterCriticalSection benutzen ?!
Vielen dank nochmal für die Hilfe.Das ist korrekt, mein Herr!