2010-08-16 24 views
1

J'écris classe thread-safe en C++. Toutes ses méthodes publiques utilisent des verrous (verrous de rotation non récursifs). Les méthodes privées sont sans verrou. Donc, tout devrait être OK: l'utilisateur appelle la méthode publique, il verrouille l'objet et ensuite le travail à travers des méthodes privées. Mais je me suis verrouillé quand une méthode publique appelle une autre méthode publique. J'ai lu que les mutex récursifs sont mauvais, parce qu'il est difficile de les déboguer. J'utilise donc stdio way de C: méthode publique Foo() ne verrouille que l'objet et appelle Foo_nolock() pour faire tout le travail. Mais je n'aime pas ces méthodes _nolock(). Je pense qu'il duplique mon code. J'ai une idée: je vais faire la classe sans verrouillage BarNoLock et classe thread-safe Bar qui n'a qu'un seul membre: une instance de BarNoLock. Et toutes les méthodes de Bar verrouilleront seulement ce membre et appellent ses méthodes. Est-ce une bonne idée ou peut-être y a-t-il de meilleurs modèles/pratiques? Merci. Mise à jour: Je sais à propos de pimpl et de bridge. Je pose des questions sur les motifs multi-thread, pas sur la POO.Ajout de verrous à la classe par la composition

Répondre

1

Je ne sais pas pourquoi les mutex récursifs seraient considérés comme mauvais, voir cette question pour une discussion d'entre eux.

Recursive Lock (Mutex) vs Non-Recursive Lock (Mutex)

Mais je ne pense pas que ce soit nécessairement votre problème parce que Win32 sections critiques prennent en charge plusieurs entrées du même thread sans bloquer. Depuis le doc:

Lorsqu'un thread possède une section critique, il peut effectuer des appels supplémentaires à EnterCriticalSection ou TryEnterCriticalSection sans bloquer son exécution. Cela empêche un thread de se bloquer lui-même en attendant une section critique qu'il possède déjà. Pour libérer sa propriété, le thread doit appeler LeaveCriticalSection une fois pour chaque fois qu'il est entré dans la section critique. Il n'y a aucune garantie quant à l'ordre dans lequel les sujets d'attente seront acquérir la propriété de la section critique

Alors peut-être que vous faisiez quelque chose d'autre tort quand vous vous supercondamnation? Avoir à contourner le fait de ne pas vous coincer sur le même mutex à partir du même thread avec une sémantique d'appel de fonction bizarre n'est pas quelque chose que vous devriez faire.

+0

bien, vous avez raison et CS est récursif. Mon application ne bloque pas en pratique, seulement en théorie. Mais je ne veux pas utiliser de verrous récursifs. – f0b0s

+0

Eh bien, si vous êtes mort contre les verrous récursifs alors ce que vous proposez semble raisonnable. Une autre chose que je dirais est que vous avez seulement rencontré des problèmes avec votre conception originale quand une fonction publique de votre objet en appelait une autre. La solution de contournement évidente serait de ne pas le faire et chaque fois que vous auriez partagé des fonctionnalités qui devaient être partagées, inscrivez-le dans une méthode privée non verrouillée. Ensuite, chaque méthode publique tire un verrou et fait son travail et les méthodes privées utilisées ne tirent pas les verrous. – bshields

+0

bshields: ainsi, vous me conseiller de mettre toute la fonctionnalité de méthode publique dans metods privé sans blocage: Foo() -> Foo_nolock()? C'était un design original – f0b0s

1

On dirait que vous avez réinventé le Bridge Pattern. Sonne parfaitement dans l'ordre.

+0

C'est ce dont je parlais - bridge ou pimpl, ouais. Je demandais à propos des idiomes multithread, pas OOP – f0b0s