2010-05-09 2 views
11

Ich habe ein Skript in Python, das eine Ressource verwendet, die nicht von mehr als einer bestimmten Anzahl gleichzeitiger Skripts verwendet werden kann.Benannte Semaphore in Python?

Klassisch würde dies durch einen benannten Semaphoren gelöst werden, aber ich kann diese in der Dokumentation des Moduls multiprocessing oder threading nicht finden.

Fehle ich etwas oder sind Semaphoren benannt, die nicht von Python implementiert wurden? und, was noch wichtiger ist, wenn die Antwort nein ist, was ist der beste Weg, um einen zu emulieren?

Danke, Boaz

PS. Aus Gründen, die für diese Frage nicht so relevant sind, kann ich die Aufgabe nicht zu einem kontinuierlich laufenden Prozess/Daemon zusammenfassen oder mit erzeugten Prozessen arbeiten - beide scheinen mit der Python-API zu funktionieren.

Antwort

4

Ich schlage eine Drittanbieter-Erweiterung wie these vor, idealerweise die posix_ipc Eins - siehe insbesondere die sempahore Sektion in der Dokumentation.

Bei diesen Modulen geht es hauptsächlich darum, das "System V IPC" (einschließlich Semaphoren) auf unixy Weise freizulegen, aber mindestens eines davon (posix_ipc) soll mit Cygwin unter Windows arbeiten (das habe ich nicht verifiziert) Anspruch). Es gibt einige dokumentierte limitations auf FreeBSD 7.2 und Mac OSX 10.5, also seien Sie vorsichtig, wenn diese Plattformen für Sie wichtig sind.

0

Sie können sie emulieren, indem Sie das Dateisystem anstelle eines Kernel-Pfades verwenden (benannte Semaphore werden auf diese Weise auf einigen Plattformen implementiert). Sie müssen sem_[open|wait|post|unlink] selbst implementieren, aber es sollte relativ trivial sein, dies zu tun. Ihr Synchronisierungsaufwand kann erheblich sein (abhängig davon, wie oft Sie mit dem Semaphor in Ihrer App umgehen müssen). Daher sollten Sie eine Ramdisk initialisieren, wenn Sie Ihren Prozess starten, in dem benannte Semaphore gespeichert werden.

Alternativ, wenn Sie sich nicht wohl fühlen, rollen Sie Ihre eigenen, könnten Sie wahrscheinlich wickeln boost::interprocess::named_semaphore (docs here) in einem einfachen Erweiterungsmodul.

+2

Es gibt viele Möglichkeiten, das falsch zu machen (Fairness, Zeitplan, Aufwachen, Rennbedingungen). Verwenden Sie Kernel oder libc-Grundelemente (z. B. die echte sem_ * API oder die CreateSemaphore/event API in Windows); vermeiden Sie, Ihre eigenen Synchronisationsgrundelemente zu rollen. –

+1

Deshalb biete ich an, dass Sie Boost verwenden können, wenn Sie nicht selbst damit anfangen können. –