débloquage sécurisé de mutex en C++

Le
Eric Bart
Bonjour,

D'après ce que j'ai compris, une des difficultés des threads est d'être
certain de débloquer les mutex, sans quoi on risque de tout bloquer.

Je me demande si les exceptions en C++ peuvent aider à résoudre ce problème.

on pourrait écrire quelque chose comme :

try {
pthread_mutex_lock (&mutex);
/* section critique */
pthread_mutex_unlock (&mutex);
}
catch() {
/* erreur quelconque */
pthread_mutex_unlock (&mutex);
/* gestion de l'erreur */
}

Il serait ptêt même intéressant de lancer une exception en cas de timeout. Si
la thread traine trop on peut considérer qu'elle est bloquée. Comment faire ?
En utilisant une deuxième thread ?

Pouvez-vous me dire si c'est la bonne voie ? Avez-vous un exemple sur cette
base ? Ou autre chose ?

Merci
Vos réponses Page 1 / 2
Trier par : date / pertinence
Fabien LE LEZ
Le #830462
On Mon, 20 Sep 2004 19:19:39 +0200, "Eric Bart"

try {
pthread_mutex_lock (&mutex);
/* section critique */
pthread_mutex_unlock (&mutex);
}
catch(...) {
/* erreur quelconque */
pthread_mutex_unlock (&mutex);
/* gestion de l'erreur */


Déjà, ça c'est assez mauvais. Utilise plutôt le RAII.
Un lien parmi d'autres :

Ici :

class RAII_Mutex
{
public:
RAII_Mutex (Mutex& mutex_) : mutex (mutex_)
{ pthread_mutex_lock (&mutex); }
~RAII_Mutex()
{ pthread_mutex_unlock (&mutex); }
private:
Mutex& mutex;
};

Et ton code devient :

{
RAII_Mutex (mutex);
// Section critique
}

Note les accolades, qui permettent de contrôler la durée de vie de
l'objet RAII_Mutex.

Note : tu peux aussi ajouter un try/catch, dans cette fonction ou
en-dehors, pour gérer les erreurs. Mais c'est en-dehors de la gestion
du mutex.


--
;-)

Serge Paccalin
Le #830461
Le lundi 20 septembre 2004 à 21:10, Fabien LE LEZ a écrit dans
fr.comp.lang.c++ :

class RAII_Mutex
{
public:
RAII_Mutex (Mutex& mutex_) : mutex (mutex_)
{ pthread_mutex_lock (&mutex); }
~RAII_Mutex()
{ pthread_mutex_unlock (&mutex); }
private:
Mutex& mutex;
};

Et ton code devient :

{
RAII_Mutex (mutex);


RAII_Mulex lock(mutex);

// Section critique
}

Note les accolades, qui permettent de contrôler la durée de vie de
l'objet RAII_Mutex.


--
___________ 2004-09-21 08:40:16
_/ _ _`_`_`_) Serge PACCALIN -- sp ad mailclub.net
_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763

Fabien LE LEZ
Le #830460
On Tue, 21 Sep 2004 08:41:07 +0200, Serge Paccalin

RAII_Mulex lock(mutex);


Oups, oui, désolé...

--
Demain j'arrête de boire...

Eric Bart
Le #830457
Merci

Je comprends le principe du RAII mais j'ai du mal dans le détail.

class RAII_Mutex
{
public:
RAII_Mutex (Mutex& mutex_) : mutex (mutex_)
{ pthread_mutex_lock (&mutex); }


je ne comprends pas: " : mutex (mutex_)"
La classe RAII_Mutex descend-elle d'une autre classe ?
Où trouver cette classe ? J'utilise glib

~RAII_Mutex()
{ pthread_mutex_unlock (&mutex); }
private:
Mutex& mutex;
};

Et ton code devient :

{
RAII_Mulex lock(mutex);


Je suppose que lock() vient de la classe parente


// Section critique
}

Note les accolades, qui permettent de contrôler la durée de vie de
l'objet RAII_Mutex.


Je ne connais pas cette utilisation des accolades. Exite-t-elle dans la
glib ?


Merci

Richard Delorme
Le #830456
class RAII_Mutex
{
public:
RAII_Mutex (Mutex& mutex_) : mutex (mutex_)
{ pthread_mutex_lock (&mutex); }



je ne comprends pas: " : mutex (mutex_)"


Ça initialise le membre mutex avec mutex_, un peu comme si, à
mutex = mutex_;

La classe RAII_Mutex descend-elle d'une autre classe ?


Non.

RAII_Mulex lock(mutex);


Je suppose que lock() vient de la classe parente


Non. lock est un nom de variable (une instance de la classe RAII_Mutex).
lock(mutex) appelle le constructeur.

Note les accolades, qui permettent de contrôler la durée de vie de
l'objet RAII_Mutex.


Je ne connais pas cette utilisation des accolades. Exite-t-elle dans la
glib ?


Uh ? Cette utilisation des accolades n'a aucun lien avec une quelconque
bibliothèque.

PS : achète toi un bon livre sur le C++. Les « détails » sur lesquels tu
butes sont quand même les bases du langage C++ actuel.

--
Richard


Arnaud Meurgues
Le #830244
Eric Bart wrote:

class RAII_Mutex
{
public:
RAII_Mutex (Mutex& mutex_) : mutex (mutex_)
{ pthread_mutex_lock (&mutex); }



je ne comprends pas: " : mutex (mutex_)"
La classe RAII_Mutex descend-elle d'une autre classe ?


Non. mutex est un membre de la classe RAII_Mutex défini un peu plus bas :

private:
Mutex& mutex;

Et l'on initialise ce membre avec le paramètre du constructeur de
RAII_Mutex.

Mutex n'est pas forcément le vrai type, mais un nom générique
correspondant au type des mutex du système (le type du paramètre de
pthread_mutex_lock(), qui pourrait, par exemple, être pthread_mutex_t).

Et ton code devient :

{
RAII_Mulex lock(mutex);



Je suppose que lock() vient de la classe parente


Non, Là, lock est le nom d'une variable de type RAII_Mutex construite
avec le paramètre mutex.

Je ne connais pas cette utilisation des accolades. Exite-t-elle dans la
glib ?


L'utilisation des accolades n'est pas propre à une bibliothèque, mais
est une spécification de C++. Une accolade fermante détruit toutes les
variables qui ont été déclarées depuis l'accolade ouvrante correspondante.

{
UnType uneVariable;
// tout un tas de choses
}

À l'accolade fermante, on est assuré par C++ que le destructeur de
uneVariable (défini dans le type UnType) sera appelé. Dans le cas d'une
mutex, on est donc assuré que le destructeur du RAII_Mutex sera appelé,
et donc que la mutex sera libérée, quelque soit la façon dont on sort du
bloc d'accolades (return ou exception).

--
Arnaud
(Supprimez les geneurs pour me répondre)


Eric Bart
Le #830243
"Richard Delorme" "Arnaud Meurgues"
Merci à vous deux.

PS : achète toi un bon livre sur le C++. Les « détails » sur lesquels tu
butes sont quand même les bases du langage C++ actuel.


Je n'ai rien trouvé dans mes bouquins C/C++ Delanoy (1998) sur
les accolades qui déterminent une zone locale. Passons...

Pareil pour l'initialisation. Ainsi :

RAII_Mutex (pthread_mutex_t & mutex_) : mutex (mutex_)
{ pthread_mutex_lock (&mutex); }

est équivalent à :

RAII_Mutex (pthread_mutex_t & mutex_)
{
mutex = mutex_;
pthread_mutex_lock (&mutex);
}


Je suppose que la première forme permet de guarantir l'initialisation.
Dans mon bouquin Delanoy, je ne trouve pas cette forme d'initialisation.

Marc Boyer
Le #830242
In article
PS : achète toi un bon livre sur le C++. Les « détails » sur lesquels tu
butes sont quand même les bases du langage C++ actuel.


Je n'ai rien trouvé dans mes bouquins C/C++ Delanoy (1998) sur
les accolades qui déterminent une zone locale. Passons...


Ce qui tendrais à prouver que ce bouquin n'est pas bon ;-)

Pareil pour l'initialisation. Ainsi :

RAII_Mutex (pthread_mutex_t & mutex_) : mutex (mutex_)
{ pthread_mutex_lock (&mutex); }

est équivalent à :

RAII_Mutex (pthread_mutex_t & mutex_)
{
mutex = mutex_;
pthread_mutex_lock (&mutex);
}


Je crois que dans ce cas là, elles le sont (pas de
constructeur ni destructeur pour pthread_mutex_t).

Je suppose que la première forme permet de guarantir l'initialisation.
Dans mon bouquin Delanoy, je ne trouve pas cette forme d'initialisation.


Ce n'est donc définitivement pas un bon bouquin de C++.

Marc Boyer
--
La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...


Matthieu Moy
Le #830241
"Eric Bart"
RAII_Mutex (pthread_mutex_t & mutex_) : mutex (mutex_)
{ pthread_mutex_lock (&mutex); }

est équivalent à :

RAII_Mutex (pthread_mutex_t & mutex_)
{
mutex = mutex_;
pthread_mutex_lock (&mutex);
}


« équivalent », pas tout à fait : la première forme te permet
d'initialiser une constante par exemple, ce que ne te permet pas la
seconde. Si mutex n'a pas de constructeur par défaut, la première
forme est la seule autorisée, ... Pour des types simples, ça n'est pas
très différent, mais si tu as des classes avec des
constructeurs/destructeurs non-triviaux, il y a une vraie différence.

En fait, il faut lire « : mutex (mutex_) » comme « construire mutex en
appelant son constructeur avec mutex_ en argument ». Ca doit s'appeler
« chainage de constructeurs » ou quelque chose comme ça dans un bon
bouquin.

--
Matthieu

Eric Bart
Le #830240
"Matthieu Moy"
En fait, il faut lire « : mutex (mutex_) » comme « construire mutex en
appelant son constructeur avec mutex_ en argument ». Ca doit s'appeler
« chainage de constructeurs » ou quelque chose comme ça dans un bon
bouquin.


« chainage de constructeurs » ... Ah OK. Merci. Bon je vais trouver un
bon bouquin ...

Publicité
Poster une réponse
Anonyme