C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

recursive, timed ReadWrite Mutex
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Ernst Murnleitner
Guest





PostPosted: Sun Sep 03, 2006 11:57 pm    Post subject: recursive, timed ReadWrite Mutex Reply with quote



Hallo,

Ich verwende boost::recursive_timed_mutex. Nun lese ich eine std::list
oft aus aber schreibe selten was rein (mehrere Threads).

Daher wäre ein ReadWrite-Mutex sinnvoller. Jetzt habe ich gesehen, dass
ein solcher Mutex bei boost 1.32 dazugekommen ist, aber bei 1.33 wegen
deadlock-Problemen wieder rausgenommen wurde.

Unter
http://paulbridger.net/read_write_lock
habe ich einen Quellcode gefunden, der einen read_write-Mutex aufbauend
auf boost definiert. Leider ist diese Lösung nicht rekursiv, und wenn
ich im gleichen Thread hintereinander WriteLock und dann ReadLock
aufrufe hängt das ganze.

Gibt es eine fertige Lösung, am besten aufbauend auf boost. Es wäre auch
möglich oben genannten Quellcode anzupassen. Ich habe aber noch nicht
gefunden, wie boost::threads beim rekursiven Mutex über die Threads Buch
führt.



Ernst
Back to top
Markus Schaaf
Guest





PostPosted: Mon Sep 04, 2006 5:30 am    Post subject: Re: recursive, timed ReadWrite Mutex Reply with quote



"Ernst Murnleitner" <mur (AT) awite (DOT) de> schrieb:

Quote:
Ich verwende boost::recursive_timed_mutex. Nun lese ich eine std::list
oft aus aber schreibe selten was rein (mehrere Threads).

Daher wäre ein ReadWrite-Mutex sinnvoller. Jetzt habe ich gesehen, dass
ein solcher Mutex bei boost 1.32 dazugekommen ist, aber bei 1.33 wegen
deadlock-Problemen wieder rausgenommen wurde.

Entschuldige, daß ich nichts zu Deiner Frage beitrage, aber es
interessiert mich: Hast Du ein spezifisches Interesse am Boost-
API oder geht es Dir doch eher um Performance?
Back to top
Christoph Bartoschek
Guest





PostPosted: Mon Sep 04, 2006 2:06 pm    Post subject: Re: recursive, timed ReadWrite Mutex Reply with quote



Ernst Murnleitner wrote:

Quote:
Hallo,

Ich verwende boost::recursive_timed_mutex. Nun lese ich eine std::list
oft aus aber schreibe selten was rein (mehrere Threads).

Hallo,

ist es dir nicht möglich das so zu designen, dass ein rekuriver Mutex nicht
notwendig ist? Rekursive Mutexe sind eher ein Zeichen von schlechtem
Design. Hier findest du ein paar Argumente und in anderen Threads der
Gruppe zu rekursiven Locks:

http://groups.google.com/group/comp.programming.threads/msg/c35bff47894fa490

Da die Boost Threads auf dem Pthread Design basieren, gelten die Argumente
auch dafür.

Christoph
Back to top
Torsten Robitzki
Guest





PostPosted: Mon Sep 04, 2006 10:14 pm    Post subject: Re: recursive, timed ReadWrite Mutex Reply with quote

Ernst Murnleitner wrote:

Quote:
Hallo,

Ich verwende boost::recursive_timed_mutex. Nun lese ich eine std::list
oft aus aber schreibe selten was rein (mehrere Threads).

Wow, was macht man den mit so einem Monster?

Quote:
Daher wäre ein ReadWrite-Mutex sinnvoller. Jetzt habe ich gesehen, dass
ein solcher Mutex bei boost 1.32 dazugekommen ist, aber bei 1.33 wegen
deadlock-Problemen wieder rausgenommen wurde.


Gibt es eine fertige Lösung, am besten aufbauend auf boost. Es wäre auch
möglich oben genannten Quellcode anzupassen. Ich habe aber noch nicht
gefunden, wie boost::threads beim rekursiven Mutex über die Threads Buch
führt.

Neben den Anmerkungen von Christoph, das rekursive Mutexe echt ein
Designproblem haben (man braucht sie einfach nicht), hier zwei "Lösungen"

1) In der Mutexklasse, die Du gefunden hast, könntest Du ganz komplizert
den Zähler durch einen Zähler pro thread erweitern und der bool, der
anzeigt, ob es einen schreibenden Zugriff gibt durch einen Zähler, der
zählt, wie oft schreibend zugegriffen wird ersetzen (komplizierteste
"Lösung").

2) Zähle extern vom mutex, wenn Du den mutext lockst, merkt sich der
thread, der locket, wie oft er den mutex gelockt hat und wann er den
mutex dann auch wieder frei geben muß.

3) Verwende einfach keinen rekursiven Lock. Trenne die Implemenierung
vom locken, dann hast Du eine Funktion, die davon ausgeht, das der lock
schon gehalten wird und eine Funktion, die davon ausgeht, das der lock
noch besorgt werden muß:

class foo
{
public:
void do() {
guard l(mutex_);
do_impl();
}
private:
void do_impl() {
...
do_impl(); // kein dead lock
}

};

4) Ein read-write mutex hat einen gewissen overhead, der sich eigentlich
erst dann bezahlt macht, wenn der lesende Codepfad auch entsprechend
lang ist. Bei Lesen einer handvoll ints wäre es wahrscheinlich
effektiver einen normalen, nicht rekursiven mutex zu verwenden. Es macht
auch nur Sinn, wenn auch mehrere threads in der Lage sind, gleichzeitig
durch diesen Codepfad zu laufen. Eine Liste mit mehreren threads auf
einer single processor Maschine zu durchsuchen, wäre so ein Beispiel,
bei dem effektiv sowieso immer nur ein thread laufen wird.

mfg Torsten
Back to top
Ernst Murnleitner
Guest





PostPosted: Tue Sep 05, 2006 2:31 am    Post subject: Re: recursive, timed ReadWrite Mutex Reply with quote

Hallo Markus,

Quote:
Entschuldige, daß ich nichts zu Deiner Frage beitrage, aber es
interessiert mich: Hast Du ein spezifisches Interesse am Boost-
API oder geht es Dir doch eher um Performance?

Mein Interesse ist dahingehend, dass ich boost::recursive_timed_mutex
bereits einsetze. Ich finde die Lösung sehr elegant, da durch
Konstruktor/Destruktor des Lock-Objektes automatisch die Lock-Zähler des
Mutex erhöht/erniedrigt werden.

Wartbarkeit, usability etc. ist mir wichtiger als Performance. Ich weiss
jetzt gar nicht, welchen Anteil das Locking/Unlocking bei meiner
Applikation ausmacht. Aber ich denke, am meisten Zeit kann ich gewinnen,
wenn ich unnötige Locks entfernen kann, das bringt sicher mehr als
irgendwelche Low-Level Sachen.


Ernst
Back to top
Ernst Murnleitner
Guest





PostPosted: Tue Sep 05, 2006 2:57 am    Post subject: Re: recursive, timed ReadWrite Mutex Reply with quote

Hallo,


Quote:
ist es dir nicht möglich das so zu designen, dass ein rekuriver Mutex nicht
notwendig ist? Rekursive Mutexe sind eher ein Zeichen von schlechtem
Design.

Wäre eigentlich kein Problem. Aber bei einem komplexen Programm kann man
da leicht mal was doppelt sperren. Und dann hat man einen Deadlock - OK,
durch den Timed-Lock könnte man eine Warnung ausgeben und das Programm
läuft vermutlich weiter.


Hier findest du ein paar Argumente und in anderen Threads der
Quote:
Gruppe zu rekursiven Locks:

http://groups.google.com/group/comp.programming.threads/msg/c35bff47894fa490

Da die Boost Threads auf dem Pthread Design basieren, gelten die Argumente
auch dafür.


In meinem Fall hatte ich anfangs (vor Jahren) gar nicht daran gedacht,
Mutex zu verwenden. Erst als dann die ersten Abstürze kamen, hatte ich
die Threads nachgerüstet. So war es einfacher, selten Benutzte
Member-Funktionen insgesamt zu sperren, in der Art:

void A::f()
{
Lock L(m_mutex);



}

Da A::f() aber auch ander Funktionen aufrufen kann, welche ebenfalls den
Mutex sperren, musste ich rekursive_mutex verwenden. Bei neuerem bzw.
zeitkritischerem Code sperre ich auf kleinerer Ebene, in der Art:

void A::f()
{
{
Lock L(m_mutex);
m_member1 = ...
}
g();
{
Lock L(m_mutex);
m_member2 = ...
}

}

Das Argument in dem von Dir zitierten Thread ist, dass man rekursive
Locks bei sauber programmiertem Code nicht benötigt. Ich würde aber
trotzdem rekursive locks verwenden, wenn ein Deadlock unter keinen
Umständen auftreten darf.

Ernst
Back to top
Ernst Murnleitner
Guest





PostPosted: Tue Sep 05, 2006 3:02 am    Post subject: Re: recursive, timed ReadWrite Mutex Reply with quote

Quote:
Unter
http://paulbridger.net/read_write_lock
habe ich einen Quellcode gefunden, der einen read_write-Mutex aufbauend
auf boost definiert. Leider ist diese Lösung nicht rekursiv, und wenn
ich im gleichen Thread hintereinander WriteLock und dann ReadLock
aufrufe hängt das ganze.

Gibt es eine fertige Lösung, am besten aufbauend auf boost. Es wäre auch
möglich oben genannten Quellcode anzupassen.

In der Zwischenzeit habe ich den Quellcode von
http://paulbridger.net/read_write_lock so angepasst, dass rekursive
locks möglich sind. Der Mutex hält eine Map mit einem Eintrag pro Thread
der einen Lock-Counter darstellt. Wenn bereits einmal gelockt, wird nur
mehr der Lock-Counter erhöht. Umgekehrt wird er nur erniedrigt, bis man
bei 1 angekommen ist, dann findet wieder das normale Freigeben statt.

Ernst
Back to top
kanze
Guest





PostPosted: Tue Sep 05, 2006 1:32 pm    Post subject: Re: recursive, timed ReadWrite Mutex Reply with quote

Ernst Murnleitner wrote:

Quote:
ist es dir nicht möglich das so zu designen, dass ein
rekuriver Mutex nicht notwendig ist? Rekursive Mutexe sind
eher ein Zeichen von schlechtem Design.

Wäre eigentlich kein Problem. Aber bei einem komplexen
Programm kann man da leicht mal was doppelt sperren.

Wenn man es nicht im Design gehandelt hat, wohl. Da hilfen
Recursiven Locks auch nicht unbedingt.

Quote:
Und dann hat man einen Deadlock - OK, durch den Timed-Lock
könnte man eine Warnung ausgeben und das Programm läuft
vermutlich weiter.

Hier findest du ein paar Argumente und in anderen Threads der
Gruppe zu rekursiven Locks:

http://groups.google.com/group/comp.programming.threads/msg/c35bff47894fa490

Da die Boost Threads auf dem Pthread Design basieren, gelten die Argumente
auch dafür.

In meinem Fall hatte ich anfangs (vor Jahren) gar nicht daran
gedacht, Mutex zu verwenden. Erst als dann die ersten Abstürze
kamen, hatte ich die Threads nachgerüstet.

Also, die Multithreading gehörte nicht zum ursprunglichen
Design? Oder wurde nicht berücksichtigt. Ich bin also skeptisch,
ob es überhaupt funktionnieren kann.

Quote:
So war es einfacher, selten Benutzte Member-Funktionen
insgesamt zu sperren, in der Art:

void A::f()
{
Lock L(m_mutex);
}

Da A::f() aber auch ander Funktionen aufrufen kann, welche
ebenfalls den Mutex sperren, musste ich rekursive_mutex
verwenden. Bei neuerem bzw. zeitkritischerem Code sperre ich
auf kleinerer Ebene, in der Art:

void A::f()
{
{
Lock L(m_mutex);
m_member1 = ...
}
g();
{
Lock L(m_mutex);
m_member2 = ...
}
}

Das Argument in dem von Dir zitierten Thread ist, dass man
rekursive Locks bei sauber programmiertem Code nicht benötigt.

Das Argument war ehe, dass wenn man die benötigt, ist der Code
meistens nicht sauber. Was in den meisten Fällen gleich zu
anderen Problemen führt.

Ich denke, dass es aber Ausnahme geben kann. Dann aber wird von
Haus aus auf rekursiven Locks konzepiert.

Quote:
Ich würde aber trotzdem rekursive locks verwenden, wenn ein
Deadlock unter keinen Umständen auftreten darf.

Ich ehe gerade das Gegenteil. Die können tatsächliche Probleme
verstecken, ohne sie zu lösen.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Back to top
Torsten Robitzki
Guest





PostPosted: Tue Sep 05, 2006 11:02 pm    Post subject: Re: recursive, timed ReadWrite Mutex Reply with quote

Ernst Murnleitner wrote:
Quote:

Das Argument in dem von Dir zitierten Thread ist, dass man rekursive
Locks bei sauber programmiertem Code nicht benötigt. Ich würde aber
trotzdem rekursive locks verwenden, wenn ein Deadlock unter keinen
Umständen auftreten darf.

das verhindert es ja nicht, es macht einen nur glauben, das so keine
dead locks mehr möglich sind. Wenn Du selber nicht mehr weist, ob du den
einen Lock bereits an der Hand hast oder nicht, soll es erst werden,
wenn ein zweiter mutex benötigt wird. Dann müssen diese Locks immer in
der gleichen Reihenfolge gelockt werden, das geht aber nicht wirklich,
wenn man sich nicht mal sicher ist, ob man den einen mutex schon an der
Hand hat oder nicht. Condition Variablen kannst Du auch nicht verwenden,
wenn Du dir nicht sicher bist, wie häufig Du einen Mutex bereits gelockt
hast.

Wenn ein Deadlock unter keinen Umständen auftreten darf, dann würde ich
die Software so designen, das es möglichst einfach ist, sie fehlerfrei
zu implementieren und möglichst wennig Fehlerversteckungstechnik
einsetzen ;-)

mfg Torsten
Back to top
Ernst Murnleitner
Guest





PostPosted: Thu Sep 07, 2006 2:55 am    Post subject: Re: recursive, timed ReadWrite Mutex Reply with quote

kanze schrieb:

Quote:
Wenn man es nicht im Design gehandelt hat, wohl. Da hilfen
Recursiven Locks auch nicht unbedingt.

Vielleicht nicht in jedem Fall, aber in meinem Fall und in den meisten
anderen Fällen wohl doch:

Fallbeispiel: Ich habe einen Container, wo mehrere Threads reinschreiben
und rauslesen. Der erste Thread bekommt den Lock und die andere müssen
warten (jetzt mal ReadMutex und WriteMutex ausser acht gelassen). Wenn
ich für den Zugriff auf den Container einen eigenen Mutex verwende, kann
ich mir keinen Deadlock mit Rekursive-Mutex vorstellen. Wenn ich aber
einen nicht rekursiven Mutex verwende, dann ist bereits hier schluss:

f_a()
{
LOCK;
f_b();
}

f_b()
{
LOCK;
}



Quote:
In meinem Fall hatte ich anfangs (vor Jahren) gar nicht daran
gedacht, Mutex zu verwenden. Erst als dann die ersten Abstürze
kamen, hatte ich die Threads nachgerüstet.


Also, die Multithreading gehörte nicht zum ursprunglichen
Design? Oder wurde nicht berücksichtigt. Ich bin also skeptisch,
ob es überhaupt funktionnieren kann.

Nein, das war von mir falsch ausgedrückt. Ich meinte Mutex oder sonstige
Sperrmechanismen.

Viele Gruesse

Ernst
Back to top
Ernst Murnleitner
Guest





PostPosted: Thu Sep 07, 2006 3:18 am    Post subject: Re: recursive, timed ReadWrite Mutex Reply with quote

Hallo,

Quote:
Das Argument in dem von Dir zitierten Thread ist, dass man rekursive
Locks bei sauber programmiertem Code nicht benötigt. Ich würde aber
trotzdem rekursive locks verwenden, wenn ein Deadlock unter keinen
Umständen auftreten darf.


das verhindert es ja nicht, es macht einen nur glauben, das so keine
dead locks mehr möglich sind.

Sind natürlich noch möglich, aber viele Fehlerquellen fallen ja raus.

Wenn Du selber nicht mehr weist, ob du den
Quote:
einen Lock bereits an der Hand hast oder nicht, soll es erst werden,
wenn ein zweiter mutex benötigt wird. Dann müssen diese Locks immer in
der gleichen Reihenfolge gelockt werden, das geht aber nicht wirklich,
wenn man sich nicht mal sicher ist, ob man den einen mutex schon an der
Hand hat oder nicht. Condition Variablen kannst Du auch nicht verwenden,
wenn Du dir nicht sicher bist, wie häufig Du einen Mutex bereits gelockt

OK, bei solchen Problemen. Ich verwende den Mutex nicht für Warten auf
ein Ereignis, sondern nur für den Zugriff auf Membervariablen, Strings
usw. Im Prinzip besitzt jede (Basis-)Klasse einen Mutex. Andernfalls
würde ich trylocks verwenden und beim nächsten Zyklus erneut probieren.
Aber das muss man auch beim Design berücksichtigen:

Es handelt sich um ein Automatisierungsprogramm, wo mehrer Threads
zyklich immer wieder ausgeführt werden (ähnlich einer
speicherprogrammierbaren Steuerung). Da habe ich für jeden Zyklus eine
Laufzeitüberwachung. Eigene Threads gibt es für Logging,
Benutzeroberfläche, Alarmierung etc.

Ernst
Back to top
Ernst Murnleitner
Guest





PostPosted: Thu Sep 07, 2006 3:53 am    Post subject: Re: recursive, timed ReadWrite Mutex Reply with quote

Hallo,

Quote:

1) In der Mutexklasse, die Du gefunden hast, könntest Du ganz komplizert
den Zähler durch einen Zähler pro thread erweitern und der bool, der
anzeigt, ob es einen schreibenden Zugriff gibt durch einen Zähler, der
zählt, wie oft schreibend zugegriffen wird ersetzen (komplizierteste
"Lösung").

Diese Lösung habe ich realisiert. Da ich eine ID für jeden thread habe,
habe ich es mit einer std::map realisiert.


Quote:
2) Zähle extern vom mutex, wenn Du den mutext lockst, merkt sich der
thread, der locket, wie oft er den mutex gelockt hat und wann er den
mutex dann auch wieder frei geben muß.

Da finde ich 1) praktikabler und intuitiver.


Quote:
3) Verwende einfach keinen rekursiven Lock. Trenne die Implemenierung
vom locken, dann hast Du eine Funktion, die davon ausgeht, das der lock
schon gehalten wird und eine Funktion, die davon ausgeht, das der lock
noch besorgt werden muß:

class foo
{
public:
void do() {
guard l(mutex_);
do_impl();
}
private:
void do_impl() {
...
do_impl(); // kein dead lock
}

};


Ja, das erscheint mir auch die beste Lösung. Bei Deinem Beispiel darf
aber dann die public do() keine andere public-Funktion der Klasse
aufrufen (vorausgesetzt die enthält auch einen Lock mit dem selben
Mutex). Wenn doch, dann würde ein rekurviver Mutex hier abhilfe bringen
ohne dass meiner Meinung eine weitere Gefahr eines Deadocks auftreten
würde.

Das Problem ist bei mir, dass ich zwar die Klassenstruktur gut überlegt
habe, bei der Implementation aber anfangs aus schlampigkeit bzw.
zeitersparnis alle Member-Funktionen "public" gemacht hatte, also bei
einem Teil der Klassen keine Klare Trennung zwischen Interface und
privaten Memberfunktionen existiert. Das Resultat ist in etwa so, wie
wenn do_impl() auch noch "guard l(mutex_) enthalten wuerde.

Bei vielen Features von C++ denkt man sich anfangs, dass die wohl nur
akademischer Natur sind. Im Laufe der Zeit kann man dann doch das meiste
sehr gut gebrauchen.


Quote:
4) Ein read-write mutex hat einen gewissen overhead, der sich eigentlich
erst dann bezahlt macht, wenn der lesende Codepfad auch entsprechend
lang ist. Bei Lesen einer handvoll ints wäre es wahrscheinlich
effektiver einen normalen, nicht rekursiven mutex zu verwenden. Es macht
auch nur Sinn, wenn auch mehrere threads in der Lage sind, gleichzeitig
durch diesen Codepfad zu laufen. Eine Liste mit mehreren threads auf
einer single processor Maschine zu durchsuchen, wäre so ein Beispiel,
bei dem effektiv sowieso immer nur ein thread laufen wird.

In meinem Fall gibt es mehrere längere Lesethreads und nur einen kurzen
Schreibthread. Da gerade der Schreibthread zwar selten schreibt, aber
nicht aufgehalten werden soll, erachte ich eine Read/Write-Mutex in
diesem speziellen Fall für sinnvoll.


Ernst
Back to top
Andreas Huennebeck
Guest





PostPosted: Thu Sep 07, 2006 9:11 am    Post subject: Re: recursive, timed ReadWrite Mutex Reply with quote

Ernst Murnleitner wrote:

Quote:
kanze schrieb:

Wenn man es nicht im Design gehandelt hat, wohl. Da hilfen
Recursiven Locks auch nicht unbedingt.

Vielleicht nicht in jedem Fall, aber in meinem Fall und in den meisten
anderen Fällen wohl doch:

Fallbeispiel: Ich habe einen Container, wo mehrere Threads reinschreiben
und rauslesen. Der erste Thread bekommt den Lock und die andere müssen
warten (jetzt mal ReadMutex und WriteMutex ausser acht gelassen). Wenn
ich für den Zugriff auf den Container einen eigenen Mutex verwende, kann
ich mir keinen Deadlock mit Rekursive-Mutex vorstellen. Wenn ich aber
einen nicht rekursiven Mutex verwende, dann ist bereits hier schluss:

f_a()
{
LOCK;
f_b();
}

f_b()
{
LOCK;
}

Ich habe diesen Thread nicht ganz verfolgt (war im Urlaub) und kenne
rekursive Locks nicht, aber ich verwende in solchen Fällen smarte Locks,
die wissen, ob sie LOCK() rufen müssen und nur dann beim Verlassen
des Scopes den LOCK wieder freigeben. Die Klasse, die LOCK()
zur Verfügung stellt, muss dann aber ebenfalls eine Funktion haben,
die zurückgibt, ob LOCK gerufen wurde.

Beispiel (ungetestet):

class MyMutex
{
public:
void lock();
void unlock();
bool isLocked() const;
private:
...
}

class SmartLock
{
public:
// constructor
SmartLock(const MyMutex& m)
: mutex(m), needsLocking(!mutex.isLocked())
{ if (needsLocking) mutex.lock(); }
// destructor
~SmartLock()
{ if (needsLocking) mutex.unlock(); }
private:
MyMutex mutex;
bool needsLocking;
};

Anwendung:
f_a()
{
SmartLock LOCK(resource);
f_b();
}

f_b()
{
SmartLock LOCK(resource);
}

Tschau
Andreas
--
Andreas Hünnebeck | email: acmh (AT) gmx (DOT) de
----- privat ---- | www : http://www.huennebeck-online.de
Fax/Anrufbeantworter: 0721/151-284301
GPG-Key: http://www.huennebeck-online.de/public_keys/andreas.asc
PGP-Key: http://www.huennebeck-online.de/public_keys/pgp_andreas.asc
Back to top
Torsten Robitzki
Guest





PostPosted: Thu Sep 07, 2006 11:15 pm    Post subject: Re: recursive, timed ReadWrite Mutex Reply with quote

Ernst Murnleitner wrote:
Quote:

Hallo,

Hallo Ernst,
Quote:


1) In der Mutexklasse, die Du gefunden hast, könntest Du ganz
komplizert den Zähler durch einen Zähler pro thread erweitern und der
bool, der anzeigt, ob es einen schreibenden Zugriff gibt durch einen
Zähler, der zählt, wie oft schreibend zugegriffen wird ersetzen
(komplizierteste "Lösung").

2) Zähle extern vom mutex, wenn Du den mutext lockst...

Da finde ich 1) praktikabler und intuitiver.

Da must Du zuerst die thread-id ermitteln, mit etwas Glück ist das keine
teure Aktion, muß aber nicht so sein. Dann lockst Du einen Mutex, um die
thread-id in der map nach zu schlagen um dann zu erkennen, das das ganze
ein null-Aktion war, da Du den Mutex schon hältst. Verglichen mit einem
einfacherem design ist das für mich nicht intuitiv ;-)

Quote:

3) Verwende einfach keinen rekursiven Lock. Trenne die Implemenierung
vom locken

Ja, das erscheint mir auch die beste Lösung. Bei Deinem Beispiel darf
aber dann die public do() keine andere public-Funktion der Klasse
aufrufen (vorausgesetzt die enthält auch einen Lock mit dem selben
Mutex).

Richtig, die public Funktionen locken den Mutex (oder Mutexe in einer
definierten Reihenfolge wenn mehrere nötig sind) und rufen dann eine der
Implementierungsfuntkionen. Diese dürfen dann keine öffentlichen
Funktionen rufen.

Quote:
Wenn doch, dann würde ein rekurviver Mutex hier abhilfe bringen
ohne dass meiner Meinung eine weitere Gefahr eines Deadocks auftreten
würde.

Anders herum wird ein Schuh draus. Anstatt mit einem rekursiven mutex
mögliche Fehler zu verbergen könntest Du einen debug-Mutex
implementieren, der speichert, ob und von wem (thread-id) er gehalten
wird. Kommt dann noch mal die gleiche thread-id und möchte den mutex
locken, oder wird der Mutex von einem thread frei gegeben, der den mutex
gar nicht hält, hast Du einen Fehlersitation erkannt und brichst das
Programm mit einem assert ab.

Quote:
In meinem Fall gibt es mehrere längere Lesethreads und nur einen kurzen
Schreibthread. Da gerade der Schreibthread zwar selten schreibt, aber
nicht aufgehalten werden soll, erachte ich eine Read/Write-Mutex in
diesem speziellen Fall für sinnvoll.

Klar, dafür sind die Dinger ja da.


mfg Torsten
Back to top
Hubert Schmid
Guest





PostPosted: Thu Sep 07, 2006 11:21 pm    Post subject: Re: recursive, timed ReadWrite Mutex Reply with quote

Andreas Huennebeck <acmh (AT) gmx (DOT) de> writes:

Quote:
Beispiel (ungetestet):

class MyMutex
{
public:
void lock();
void unlock();
bool isLocked() const;
private:
...
}

class SmartLock
{
public:
// constructor
SmartLock(const MyMutex& m)
: mutex(m), needsLocking(!mutex.isLocked())
{ if (needsLocking) mutex.lock(); }
// destructor
~SmartLock()
{ if (needsLocking) mutex.unlock(); }
private:
MyMutex mutex;
bool needsLocking;
};

Anwendung:
f_a()
{
SmartLock LOCK(resource);
f_b();
}

f_b()
{
SmartLock LOCK(resource);
}

Ich finde den Code merkwürdig: Wenn ich das richtig verstehe, dann
sperrt der Konstruktor der Klasse SmartLock den Mutex nur, wenn er
noch nicht gesperrt ist. Wenn zwei Threads gleichzeitig die Funktion
f_b ausführen, dann sperrt der erste Thread den Mutex und läuft weiter
und der zweite Thread läuft einfach so weiter, so dass dann zwei
Threads gleichzeitig den Rumpf der Funktion ausführen, was eigentlich
der Mutex verhindern sollte. Kannst du das erklären?

--
Hubert Schmid - http://www.z42.de
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.