Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

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

18 réponses
Avatar
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

10 réponses

1 2
Avatar
Fabien LE LEZ
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 :
<http://www.google.com/groups?safe=images&ie=UTF-8&as_ugroup=fr.comp.lang.c%2b%2b&as_umsgidÎh0gh%24i11%241%40news-reader3.wanadoo.fr&as_drrb=b&as_mind&as_minm=5&as_miny 04&as_maxd &as_maxm=9&as_maxy 04&lr=&hl=en>

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.


--
;-)

Avatar
Serge Paccalin
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

Avatar
Fabien LE LEZ
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...

Avatar
Eric Bart
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

Avatar
Richard Delorme
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


Avatar
Arnaud Meurgues
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)


Avatar
Eric Bart
"Richard Delorme" wrote in message news:4150270b$0$15753
"Arnaud Meurgues" wrote in message news:415027a2$0

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.

Avatar
Marc Boyer
In article <41504018$0$17705$, Eric Bart wrote:
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...


Avatar
Matthieu Moy
"Eric Bart" writes:

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

Avatar
Eric Bart
"Matthieu Moy" wrote in message

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 ...

1 2