2010-05-10 15 views
3

Lors de l'utilisation de mmap() pour la mémoire partagée (à partir de Linux ou d'autres systèmes UNIX) est-il possible (et portable) d'utiliser les fonctions fcntl() (ou flock() ou lockf()) pour coordonner l'accès au mappage?Coordination de mmap partagée à l'aide de verrous fcntl?

Les réponses à this SO question semble suggérer que cela devrait fonctionner.

L'idée que j'ai en tête serait de structurer la mémoire partagée avec un mappage processus/page pour minimiser la contention de verrouillage. Les processus peuvent chacun fonctionner avec leurs pages simultanément, et un verrou ne doit être acquis que lors de la mise à jour des mappages de processus/pages. (L'accès en lecture à partir de pages sans propriétaire impliquerait de vérifier un numéro de série, de copier les données désirées, puis de valider que le numéro de série de ce bloc n'avait pas changé). Conceptuellement chaque processus partageant ce mappage de fichiers effectuerait le mmap(), y trouver un bloc libre, acquérir un verrou à la zone de processus/page, mettre à jour avec sa propre affectation, libérer le verrou, puis continuer joyeusement son travail . Tout processus peut rechercher des mappages périmés (en utilisant kill() avec zéro comme signal) et nettoyer le mappage de processus/table de pages.

(En termes grossiers et génériques, je suis en train de jouer avec un moteur de production/consommateur utilisant la mémoire partagée de Python sur Linux, je voudrais que la solution soit portable à BSD et à d'autres langages de programmation. tant que le support mmap() et les interfaces nécessaires à fcntl(), flock() ou lockf(). Je serais également intéressé par psuedo code montrant comment on mesurerait la contention de verrouillage et de détecter les défauts de synchronisation. Je suis conscient que le filetage et multitraitement avec leurs objets Queue() respectifs sont la manière la plus simple d'implémenter un modèle de traitement Python producteur/consommateur).

Répondre

1

Je suis sûr que les verrous offriront une exclusion mutuelle, mais je ne sais pas s'ils vous donneront une barrière de mémoire. Il semble que sauter dans le noyau (ce que font fcntl, flock, et lockf) est susceptible de faire quelque chose qui force la lecture et l'écriture de la mémoire hors service à commettre, mais je doute que vous ayez une garantie absolue. Je pense que c'est une de ces choses où cela fonctionne probablement, et les tests montreront que cela fonctionne, mais vous ne saurez pas que cela fonctionne toujours à moins de trouver une référence en disant autant.

J'ai fait quelque chose de similaire à partir de C, mais j'ai utilisé des spinlocks atomiques dans la mémoire partagée elle-même. Il fut un temps que vous deviez faire un peu de montage en ligne, mais gcc a maintenant quelques opérations intrinsèques que vous pouvez utiliser:

http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html

Si vous êtes prêt à écrire une extension Python très simple, vous pouvez envelopper __sync_lock_test_and_set (...) et __sync_lock_release (...) pour faire ce dont vous avez besoin. Ceux-ci devraient être assez portables.

Je crois qu'il existe un moyen de mettre des mutex pthread dans la mémoire partagée, mais je n'en ai aucune expérience. Encore une fois, vous devrez écrire une simple extension C pour y accéder depuis Python.

+1

Pas besoin d'écrire une extension Python en fait. Vous pouvez utiliser le module 'ctypes' de Python pour accéder à la bibliothèque C directement via le code Python. (Vous avez toujours besoin d'une bonne quantité de connaissances sur C si) – intgr