Dies ist der relevanteste Teil des Codes aus dem Beispiel:
Code: Select all
# File lock class for synchronizing write access to /tmp.
class FileLock:
def __enter__(self):
self._lock = threading.Lock()
self._lock.acquire()
self._fd = open('/tmp/lockfile.LOCK', 'w+')
fcntl.lockf(self._fd, fcntl.LOCK_EX)
def __exit__(self, type, value, traceback):
self._fd.close()
self._lock.release()
# Get the location of the import directory. Snowflake sets the import
# directory location so code can retrieve the location via sys._xoptions.
IMPORT_DIRECTORY_NAME = "snowflake_import_directory"
import_dir = sys._xoptions[IMPORT_DIRECTORY_NAME]
# Get the path to the ZIP file and set the location to extract to.
zip_file_path = import_dir + "spacy_en_core_web_sm.zip"
extracted = '/tmp/en_core_web_sm'
# Extract the contents of the ZIP. This is done under the file lock
# to ensure that only one worker process unzips the contents.
with FileLock():
if not os.path.isdir(extracted + '/en_core_web_sm/en_core_web_sm-2.3.1'):
with zipfile.ZipFile(zip_file_path, 'r') as myzip:
myzip.extractall(extracted)
Der Code ist größtenteils sinnvoll, bis auf ein Bit. Welchen Sinn hat es, eine threading.Lock-Instanz in der __enter__-Methode der FileLock-Klasse zu erstellen und diese zu erwerben? Wenn dies dazu gedacht ist, die Threads zu synchronisieren, wäre es dann nicht sinnvoll, das Sperrobjekt irgendwie zwischen den Threads zu teilen? Andernfalls erstellt jeder Thread seine eigene Instanz der Sperre und erhält sie. Wie würde das irgendetwas bewirken?
Ich glaube, dass der Code seinen Zweck tatsächlich durch die Verwendung der Dateisperre erreicht, die tatsächlich von allen Threads/Prozessen, die diesen Code ausführen, gemeinsam genutzt wird, da es sich um eine exklusive Dateisperre für ein und dieselbe Datei für alle handelt. Übersehe ich etwas und die Verwendung der Dateisperre reicht hier nicht aus und die threading.Lock wird auch benötigt?
Mobile version