J'ai mis en œuvre deux applications qui partagent des données à l'aide de l'API de mémoire partagée POSIX (I.E. shm_open code>). Un processus met à jour des données stockées dans le segment de mémoire partagée et un autre processus le lit. Je souhaite synchroniser l'accès à la région de mémoire partagée en utilisant une sorte de mutex ou de sémaphore. Quelle est la façon la plus efficace de faire cela? Certains mécanismes que je considère sont p>
Semget Code> Li>
ul>
4 Réponses :
plutôt qu'un système V Semaphore, j'irais avec un POSIX nommé sémaphore en utilisant SEM_OPEN () code>, etc. p>
POSIX garantit-il que de tels sémaphores peuvent être partagés entre les processus? (Semble logique, mais je ne trouve pas le libellé.) sem_init code> ( Pshared code> True fonctionnerait certainement pour cette application, puisqu'il a déjà le segment de mémoire partagé.
À l'aide du sémaphore POSIX ajouté Aucun frais de vue remarquable et API est très simple.
Soyez prudent, les sémaphores sont une fonctionnalité facultative de POSIX. De plus, il existe des implémentations désagréables qui "implémentent" sem_init code> en définissant simplement un code d'erreur. Afair OSX est un tel système.
Si l'efficacité est importante, j'irais avec les mutiles et les variables de condition partagés du processus. P>
Afair, chaque opération avec un sémaphore nécessite un système SYSCALL, donc Mutex non compris doit être plus rapide que le sémaphore [AB] utilisé à la manière de type mutex. P>
Typiquement SEM_POST CODE> devrait simplement être un incrément atomique et ne pas aboutir à un syscall.
pourrait aussi bien faire une réponse. P>
Vous pouvez utiliser SEM_INIT avec Quant à savoir si cela est plus rapide ou plus lent qu'un mutex et une variable de condition partagée, seul le profilage peut vous dire. Sur Linux, je soupçonne qu'ils sont tous assez similaires car ils s'appuient sur la machinerie "Futex". P> Pshared code > True pour créer un sémaphore POSIX dans votre espace mémoire partagé. J'ai utilisé cela avec succès dans le passé. P>
Premièrement, vraiment référence à savoir si la performance est importante. Le coût de ces choses est souvent surestimé. Donc, si vous ne trouvez pas que l'accès à la structure de contrôle est de même ordre de grandeur que les écritures, il suffit de prendre tout ce que la construction est sémantiquement la meilleure pour votre cas d'utilisation. Ce serait le cas habituellement si vous auriez environ 100 octets écrits par accès à la structure de contrôle. P>
Sinon, si la structure de contrôle est le goulot d'étranglement, vous devez peut-être éviter de les utiliser. C11 a le nouveau concept de _atomic code> types et opérations pouvant être utilisés dans des cas où il y a des courses dans l'accès aux données. C11 n'est pas encore largement mis en œuvre, mais tous les compilateurs modernes ont probablement des extensions qui implémentent ces fonctionnalités déjà. P>
Les mécanismes de synchronisation standard C11 et C ++ 11 fonctionnent-ils entre les processus? (Les normes ont-elles même un concept de "à travers les processus"?)
Non, ils n'ont pas de concept de mémoire partagée. Néanmoins, le processeur sous-jacent comporte que tous les processeurs modernes doivent fournir cette fonctionnalité devrait être complètement agnostique sur cette question. Ils agissent directement sur la mémoire qui leur est présentée.
Il n'y a aucune garantie que les mécanismes standard se synchroniseront correctement entre les processus. Par exemple, un environnement multi-threadé peut utiliser une bibliothèque de filetage de l'espace utilisateur sans support de noyau pour la préemption. Dans ce cas, les primitives de synchronisation pourraient ne pas gêner la synchronisation de la mémoire avec des barrières appropriées. (Peu probable? Bien sûr. Mais certainement autorisé par la norme, en faisant une mauvaise réponse à la question telle que formulée.)
J'ai des difficultés à imaginer comment vous pouvez assurer une synchronisation correcte des opérations atomiques entre les threads qui ne feraient pas la même chose entre les processus. En tout état de cause, vous auriez un passage de contexte pour gérer entre les threads. Mais que ce soit, vous avez raison que POSIX n'a pas encore le temps de réagir sur C11. Toutes les versions précédentes de la norme C ont toujours été "incorporées" par référence directe dans POSIX. Et la stratégie médiocre n'est pas ma réponse, mais d'imposer toujours des structures de synchronisation pour le traitement parallèle. Les opérations atomiques sont présentes dans les CPU depuis des années, nous devrions les utiliser.
@Nemo également revenir à votre déclaration "mauvaise réponse". La réponse acceptée n'est pas bien meilleure, car les sémaphores sont des caractéristiques optionnelles de POSIX et même s'ils sont mis en œuvre, la spécification est trop faible qu'elle applique un comportement raisonnable.
Quel langage de programmation? Pour C ++ considérer
boost :: interprocesses code>.En dehors de la curiosité, pourquoi utilisez-vous un segment de mémoire partagé au lieu d'un fichier nommé sur un
TMPFS code> ouhugetlbfs code>? J'utiliserais probablement un Posix Mutex car ils ont été très rapides pendant plusieurs années sur Linux.@Tmyklebu: J'utilise une mémoire partagée pour éviter les appels système et la copie inutile des données. Une fois que les segments de mémoire partagés sont configurés, les données sont accessibles en utilisant simplement des pointeurs.
Quelle copie inutile des données se produit lorsque vous créez, développez et
mmap () code> un fichier sur unTMPFS code> ouhugetlbfs code>?