28 votes

Dans quelle situation utilisez-vous un sémaphore sur un mutex en C ++?

Tout au long des ressources que j'ai lues sur le multithreading, le mutex est plus souvent utilisé et discuté que le sémaphore. Ma question est quand utilisez-vous un sémaphore sur un mutex? Je ne vois pas de sémaphores dans le fil Boost. Cela signifie-t-il que les sémaphores n'utilisent plus beaucoup ces jours-ci?

Pour autant que je sache, les sémaphores permettent à une ressource d'être partagée par plusieurs threads. Cela n'est possible que si ces threads lisent uniquement la ressource mais pas l'écriture. Est-ce correct?

15voto

nikie Points 7479

Le cas d'utilisation typique d'un mutex (permettant à un seul thread d'accès à une ressource à tout moment) est beaucoup plus fréquente que l'on utilise si un sémaphore. Mais un sémaphore est en fait le concept plus général: Un mutex est (presque) un cas particulier d'un sémaphore.

Applications typiques: Vous ne voulez pas créer plus de (par exemple) 5 connexions de base de données. Peu importe le nombre de threads de travail il y a, ils ont à partager ces 5 connexions. Ou, si vous exécutez sur un N-core de la machine, vous voudrez peut-être faire en sorte que certains CPU/mémoire des tâches à forte intensité de ne pas l'exécuter, en plus de N threads en même temps (parce que ce serait seulement de réduire le débit en raison de changements de contexte et cache raclée effets). Vous pourriez même vouloir limiter le nombre de parallèles CPU/mémoire intensive des tâches à N-1, donc le reste du système ne peut pas mourir de faim. Ou imaginez une certaine tâche nécessite beaucoup de mémoire, le fait d'exécuter plus de N instances de la tâche dans le même temps, conduirait à la pagination. Vous pouvez utiliser un sémaphore ici, afin de s'assurer que pas plus de N instances de ce type particulier de l'exécution de la tâche en même temps.

EDIT/PS: à Partir de votre question "Ceci n'est possible que si les discussions ne sont que la lecture de la ressource, mais pas l'écriture. Est-ce correct?" et de ton commentaire, il me semble que si vous êtes à la pensée d'une ressource comme une variable ou un cours d'eau, qui peut être lu ou écrit et qui ne peut être écrit que par un seul thread à la fois. Ne le faites pas. C'est trompeur dans ce contexte.

Pensez à des ressources comme l'eau. Vous pouvez utiliser de l'eau pour laver votre vaisselle. Je peux utiliser de l'eau pour laver ma vaisselle en même temps. Nous n'avons pas besoin de tout type de synchronisation pour que, parce qu'il y a assez d'eau pour nous deux. Nous n'avons pas nécessairement utiliser la même eau. (Et vous ne pouvez pas "lu" ou "écriture" de l'eau.) Mais le montant total de l'eau est finie. Il n'est donc pas possible pour tout nombre de parties à se laver les plats en même temps. Ce type de synchronisation est effectuée avec un sémaphore. Ne pas avec de l'eau, mais avec d'autres ressources limitées comme la mémoire, l'espace disque, e / s de débit ou de cœurs de PROCESSEUR.

8voto

Tall Jeff Points 6065

L'essence de la différence entre un mutex et sémaphore a à voir avec la notion de propriété. Quand un mutex est pris, on pense de ce fil de discussion que de posséder le mutex et ce même thread doit libérer le mutex vers l'arrière pour libérer la ressource.

Pour un sémaphore, d'envisager de prendre le sémaphore de la consommation de la ressource, mais pas réellement de prise de possession. Cela est généralement considéré comme le sémaphore d'être "vide", plutôt que d'être la propriété d'un thread. La caractéristique de la sémaphore est alors qu'un autre thread peut "remplir" le sémaphore retour au "plein" de l'état.

Par conséquent, les mutex sont généralement utilisés pour la simultanéité de la protection des ressources (ex: Mutuelle EXlusion), tandis que les sémaphores sont utilisés pour la signalisation entre les threads (comme sémaphore drapeaux de signalisation entre les navires). Un mutex par lui-même ne peut pas vraiment être utilisé pour la signalisation, mais les sémaphores peuvent. Ainsi, en sélectionnant l'un sur l'autre dépend de ce que vous essayez de faire.

Voir un autre un de mes réponses ici pour plus de discussion sur un sujet connexe, couvrant la distinction entre récursives et non récursives mutex.

7voto

R Samuel Klatchko Points 44549

Pour contrôler l'accès à un nombre limité de ressources partagées par plusieurs threads (soit inter ou intra-processus).

Dans notre application, nous avons eu un très lourd de ressources et que nous ne voulons pas d'allouer un pour chacune des M threads de travail. Depuis un thread de travail nécessaire à la ressource pour seulement une petite partie de leur travail, nous avons rarement été l'utilisation de plus d'un couple de ressources simultanément.

Donc, nous avons alloué des N de ces ressources et à les mettre derrière un sémaphore initialisé à N. Lorsque plus de threads N ont essayé d'utiliser la ressource, ils viennent de le bloquer jusqu'à ce que l'un était disponible.

4voto

Steve Jessop Points 166970

Coup de pouce.Fil de discussion a les mutex et les variables de condition. Purement en termes de fonctionnalité, les sémaphores sont donc redondants[*], bien que je ne sais pas si c'est pourquoi ils sont omis.

Les sémaphores sont une base plus primitive, plus simple, et éventuellement mis en œuvre pour être plus rapide, mais n'avez pas la priorité inversion de l'évitement. Ils sont sans doute plus difficile à utiliser que les variables de condition, parce qu'ils exigent que le client afin de s'assurer que le nombre de postes "correspond à" le nombre d'attentes dans certains de manière appropriée. Avec les variables de condition, il est facile de tolérer les parasites des messages, parce que personne ne fait ne fait rien sans en vérifier l'état.

Lire vs écrire des ressources est un leurre de l'OMI, il n'a rien à voir avec la différence entre un mutex et sémaphore. Si vous utilisez un comptage sémaphore, vous pourriez avoir une situation où plusieurs threads simultanément d'accéder à la même ressource, auquel cas il ne serait sans doute d'être un accès en lecture seule. Dans cette situation, vous pourriez être en mesure d'utiliser shared_mutex de coup de pouce.Fil à la place. Mais les sémaphores ne sont pas "pour" protéger les ressources dans la façon dont les mutex sont, ils sont "pour" l'envoi d'un signal à partir d'un thread à l'autre. Il est possible de l' utiliser pour contrôler l'accès à une ressource.

Cela ne signifie pas que toutes les utilisations de sémaphores doivent se rapporter à la lecture seule de ressources. Par exemple, vous pouvez utiliser un sémaphore binaire pour protéger une lecture/écriture de ressources. Peut-être pas une bonne idée, que, depuis un mutex vous donne souvent une meilleure planification de comportement.

[*] Voici à peu près comment mettre en œuvre un comptage à l'aide d'un sémaphore mutex et une variable de condition. Pour mettre en œuvre un sémaphore partagé bien sûr, vous avez besoin d'un partagées mutex/condvar:

struct sem {
    mutex m;
    condvar cv;
    unsigned int count;
};

sem_init(s, value)
    mutex_init(s.m);
    condvar_init(s.cv);
    count = value;

sem_wait(s)
    mutex_lock(s.m);
    while (s.count <= 0) {
        condvar_wait(s.cv, s.m);
    }
    --s.count;
    mutex_unlock(s.m);

sem_post(s)
    mutex_lock(s.m);
    ++s.count;
    condvar_broadcast(s.cv)
    mutex_unlock(s.m);

Par conséquent, tout ce que vous pouvez faire avec les sémaphores, vous pouvez le faire avec les mutex et les variables de condition. Pas nécessairement par la mise en œuvre d'un sémaphore, cependant.

3voto

Lirik Points 17868

Je me sens comme il n'y a pas de moyen simple pour VRAIMENT répondre à votre question sans faire abstraction des informations importantes sur les sémaphores. Les gens ont écrit de nombreux livres sur les sémaphores, donc un ou deux paragraphe réponse est un mauvais service. Un livre populaire est Le Petit Livre de Sémaphores... pour ceux qui n'aiment pas les gros livres :).

Voici un décent long article qui va dans un grand nombre de détails sur la façon dont les sémaphores sont utilisés et la façon dont ils sont destinés à être utilisés.

Mise à jour:
Dan relevé quelques erreurs dans mes exemples, je vais le laisser avec les références qui offrent BEAUCOUP de meilleures explications que le mien :).

Voici les références montrant la bonne façon on devrait utiliser un sémaphore:
1. IBM Article
2. L'université de Chicago Conférence en Classe
3. Le Netrino article que j'ai posté.
4. Le "vendre des billets" papier + code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X