PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [Win32]CRITICAL_SECTION-Frage


Gast
2009-11-20, 19:04:14
Hallo zusammen,

Gegeben sei folgendes Win32-Programm:

CRITICAL_SECTION cs;

//...

EnterCriticalSection(&cs);
doSomething();
LeaveCriticalSection(&cs);

//...

void doSomething()
{
EnterCriticalSection(&cs);
//...
LeaveCriticalSection(&cs);
}

D.h. ich trete zweimal in demselben Thread in die CRITICAL_SECTION ein. Laut MSDN ist das kein Problem. Jetzt ist die Frage: verlasse ich die nun schon beim ersten Aufruf von LeaveCriticalSection(), also innerhalb von doSomething(), oder erst beim zweiten Aufruf, nach dem Beenden von doSomething()?

Danke für eure Hilfe.

Gast
2009-11-20, 19:42:49
wenn ich mich richtig erinnere verlässt du die cs schon beim ersten leave-aufruf. der zweite enter-aufruf funktioniert überhaupt nur, weil Win-CS reentrancefähig sind.

kann aber auch sein, dass ich mich täusche. ich verwende schon ewig die imo bequemeren boost-bibliotheken

mfg,
zgep

xxxgamerxxx
2009-11-20, 19:53:09
D.h. ich trete zweimal in demselben Thread in die CRITICAL_SECTION ein. Laut MSDN ist das kein Problem. Jetzt ist die Frage: verlasse ich die nun schon beim ersten Aufruf von LeaveCriticalSection(), also innerhalb von doSomething(), oder erst beim zweiten Aufruf, nach dem Beenden von doSomething()?

Danke für eure Hilfe.

Das ist egal, weil intern ein Counter die Locks mitzählt. D.h. du hast in dem Bsp. zwei Enter Aufrufe hintereinander, also ist der Counter für den Thread auf 2. Danach folgen die zwei Leave Aufrufe und der Counter wird um zwei dekrementiert, erst dann verliert der Thread den Lock auf den Variable.

Neomi
2009-11-20, 19:54:06
kann aber auch sein, dass ich mich täusche.

Das tust du. Es gibt einen internen Counter, der dafür sorgt, daß eine Critical Section erst dann wieder freigegeben wird, wenn auch das erste EnterCriticalSection mit einem LeaveCriticalSection gepaart wurde. In der Doku steht es auch eindeutig drin, warum wirft man bei Fragen zu einer konkreten Funktion nicht einfach einen Blick dort hinein?

http://msdn.microsoft.com/en-us/library/ms682608%28VS.85%29.aspx

"A thread must call LeaveCriticalSection once for each time that it entered the critical section."

Gast
2009-11-20, 20:06:46
In der Doku steht es auch eindeutig drin, warum wirft man bei Fragen zu einer konkreten Funktion nicht einfach einen Blick dort hinein?

http://msdn.microsoft.com/en-us/library/ms682608%28VS.85%29.aspx

"A thread must call LeaveCriticalSection once for each time that it entered the critical section."so ganz eindeutig ist das nicht, da nicht klar ersichtlich ist, ob "each time that it entered the critical section" jeden Aufruf von EnterCriticalSection() meint, oder nur der erste Aufruf als Betreten der kritischen Sektion angesehen wird, da der Thread bei jedem nachfolgenen Aufruf ja schon drin ist (Zitat aus dem Spiel Star Trek Generations: "Captain, es gibt keinen Anlass, Kurs auf dieses System zu nehmen, wir sind bereits da" ;)).

Aber trotzdem danke für die Hilfe.

Gast
2009-11-20, 20:19:18
Es gibt einen internen Counter, der dafür sorgt, daß eine Critical Section erst dann wieder freigegeben wird, wenn auch das erste EnterCriticalSection mit einem LeaveCriticalSection gepaart wurde.
ah, also quasi eine umgedrehte semaphore.

na gut, ist wie gesagt lange her bei mir, da boost imo viel einfacher zu handhaben ist (<werbung> und nebendrein mächtiger und plattformunabhängig </werbung>)

mfg, zgep

Neomi
2009-11-20, 20:24:40
so ganz eindeutig ist das nicht, da nicht klar ersichtlich ist, ob "each time that it entered the critical section" jeden Aufruf von EnterCriticalSection() meint, ...

Genau einen Satz vor dem, den ich aus der Doku schon zitiert hatte:

"The thread enters the critical section each time EnterCriticalSection and TryEnterCriticalSection succeed."

Kurz: Wenn man die Doku auch liest, ist es eindeutig. ;)

Gast
2009-11-20, 20:53:36
Genau einen Satz vor dem, den ich aus der Doku schon zitiert hatte:

"The thread enters the critical section each time EnterCriticalSection and TryEnterCriticalSection succeed."

Kurz: Wenn man die Doku auch liest, ist es eindeutig. ;)nun, ich muss gestehen, ich habe die Windows Mobile-Version gelesen, da ich für Windows Mobile progge:

http://msdn.microsoft.com/en-us/library/aa908723.aspx

Da steht's etwas anders ;)

xxxgamerxxx
2009-11-20, 21:06:16
nun, ich muss gestehen, ich habe die Windows Mobile-Version gelesen, da ich für Windows Mobile progge:

http://msdn.microsoft.com/en-us/library/aa908723.aspx

Da steht's etwas anders ;)

Lol, da steht der Satz nur nicht davor, sondern danach. ;D

Wie auch immer, es ist auch so eindeutig. Denn sonst würde da nicht stehen
"once for each time". Die Reihenfolge Enter, Leave, Enter, Leave für denselben Thread würde ja gar keinen Sinn ergeben, da der Thread ja nach dem ersten Leave schon den Lock auf die Variable verloren hätte.

Neomi
2009-11-20, 21:07:07
nun, ich muss gestehen, ich habe die Windows Mobile-Version gelesen, da ich für Windows Mobile progge:

Das ist keine unwichtige Information. API-Funktionen können sich auf unterschiedlichen Systemen unterschiedlich verhalten. Man sollte keine Eigenschaften anderer Versionen als gegeben sehen, solange sie nicht auch in der Doku zur benutzten Version stehen.

In dem Fall würde es mich schwer wundern, wenn die Funktion sich anders verhält als ihr Desktop-Pendant. Daß sie beim zweiten betreten nicht blockt, deutet auch sehr auf eine identische Funktionsweise hin. Aber um sicher zu sein, solltest du es einfach ausprobieren. Etwa so...

Thread 1:
- auf Event warten
- Loggen
- Critical Section betreten
- Critical Section verlassen
- Loggen

Thread 2:
- Critical Section betreten
- Critical Section betreten
- Critical Section verlassen
- Event setzen
- warten (z.B. 5 Sekunden)
- Loggen
- Critical Section verlassen

Edit:
Tatsache, da steht genau das gleiche drin. In dem Fall mußt du nichts ausprobieren, sondern die Brille putzen. ;)

Gast
2009-11-25, 11:34:43
Immer wieder lustig zu sehen, wie die Honks bei Microsoft nicht in der Lage sind, sinnvolle Namen zu verwenden.

Die Critical Section in Microsoft ist ein sogenannter rekursiver Mutex. Im Gegensatz dazu gibt es auch nicht rekursiven Mutexe.

xxxgamerxxx
2009-11-25, 17:00:05
Immer wieder lustig zu sehen, wie die Honks bei Microsoft nicht in der Lage sind, sinnvolle Namen zu verwenden.

Die Critical Section in Microsoft ist ein sogenannter rekursiver Mutex. Im Gegensatz dazu gibt es auch nicht rekursiven Mutexe.

Das ist eben nicht dasselbe. Ein Mutex ist in Windows ein Kernel Objekt, eine Critical Section nicht. D.h. im Umkehrschluss, dass eine Critical Section nur zur Thread Synchronisation innerhalb eines Prozesses verwendet werden kann, aber nicht prozessübergreifend.

Gast
2009-11-26, 01:05:04
Das ist eben nicht dasselbe. Ein Mutex ist in Windows ein Kernel Objekt, eine Critical Section nicht. D.h. im Umkehrschluss, dass eine Critical Section nur zur Thread Synchronisation innerhalb eines Prozesses verwendet werden kann, aber nicht prozessübergreifend.

Und was hat das mit der Namensgebung zu tun? Genau nichts. Schon gar nicht wird klar, ob ein Synchronisationsobjekt rekursiv ist oder nicht. Es spielt dabei doch gar keine Rolle, ob es ein Prozessübergreifendes Objekt ist oder nicht. Bei den Namen hat Microsoft es nicht drauf.

xxxgamerxxx
2009-11-26, 09:50:56
Und was hat das mit der Namensgebung zu tun? Genau nichts. Schon gar nicht wird klar, ob ein Synchronisationsobjekt rekursiv ist oder nicht. Es spielt dabei doch gar keine Rolle, ob es ein Prozessübergreifendes Objekt ist oder nicht. Bei den Namen hat Microsoft es nicht drauf.

Es steht doch aber in der Dokumentation (MSDN), dass eine CRITICAL_SECTION in Windows rekursiv ist :confused: Ferner ist der Begriff kritischer Abschnitt (critical section) nun mal ein geläufiger Begriff in der Informatik. Da es nun mal unterschiedliche Synchronisationsverfahren auf unterschiedlichen Lockleveln gibt, verwendet man eben auch unterschiedliche Namen.

Gast
2009-12-03, 17:36:09
nochmals was von mir ohne jede Garantie weil ich zu faul bin es nochmal nachzuschlagen:
eine CS ist in der Informatik allgemein ein Programmabschnitt, der nicht unterbrochen werden darf (keine Task-Switches, keine ISRs).
ein Mutex ist ein Mechanismus um sicherzustellen, das 2 parallel ablaufende Threads einen Bereich nicht gleichzeitig betreten könnnen, sondern nur nacheinander.
Von daher ist die Win-CS ein durch Mutex abgesicherter Programmabschnitt. Task switches/ISRs sind aber weiterhin möglich. Von daher ist der Name eigentlich falsch...

Andererseits, wayne? C++09 benutzt boost::thread als Standartbibliothek für threading und dort sind die Dinge richtig benannt => außer für prozessübergreifende Sachen ist man unabhängig von Win.

mfg,
zgep

Gast
2009-12-09, 16:01:02
nochmals was von mir ohne jede Garantie weil ich zu faul bin es nochmal nachzuschlagen:
eine CS ist in der Informatik allgemein ein Programmabschnitt, der nicht unterbrochen werden darf (keine Task-Switches, keine ISRs).oh, er darf unterbrochen werden. Nur darf während der Untebrechung kein anderer Thread die CS betreten ;)
Sehr wohl aber darf, während der unterbrochene Thread in der CS ist, ein anderer Thread etwas außerhalb des CS tun. Z.B. kann ein Worker-Thread stundenlang in einer CS rumwuseln, und dabei zahllose Mal unterbrochen werden, damit der Hauptthread die Ereignisse der graphischen Oberfläche verarbeiten kann.

Gast
2009-12-11, 10:20:54
dann unterscheidet sich das wahrscheinlich zwischen embedded und pc-systemen. auf zB RTOS und uCOS sind CS nämlich einfach so realisiert, dass ISRs global abgeschaltet werden. Dadurch finden keine Taskswitches mehr statt (Der Scheduler läuft in einem Timer Interrupt).

langsam verlerne ich dadurch, dass ich nur noch hardwarenah arbeite wohl den überblick über den ganzen rest ;)

mfg,
zgep