My goal is to lock a directory from multiple processes that will attempt to do git operations on it. I need to create the lock objects after the processes have branched based on a unique string identifier. By reading the docs, I have not found any solution in the multiprocessing module.
Here is the code demonstrating the problem:
from multiprocessing import Lock, Process
import os
import time
class NamedResource:
def __init__(self, identifier: str):
self.identifier = identifier
self.lock = Lock()
def work_on(name: str):
nr = NamedResource(name)
with nr.lock:
print(time.time() % 100 // 1, os.getpid(), f"working on {nr.identifier}")
time.sleep(5)
print(time.time() % 100 // 1,os.getpid(), f"done with {nr.identifier}")
res = ['a', 'b']
processes = []
for r in res:
p1 = Process(target=work_on, args=(r,))
p1.start()
p2 = Process(target=work_on, args=(r,))
p2.start()
processes += [p1, p2]
for p in processes:
p.join()
obviously lock objects are different, and they do not prevent the access - as can be seen from the output:
67.0 48689 working on b
67.0 48690 working on b
67.0 48688 working on a
67.0 48687 working on a
72.0 48689 done with b
72.0 48690 done with b
72.0 48688 done with a
72.0 48687 done with a
correct output would be having only one process work on each of [a, b], but two processes working at a time (because there are two different resources that do not interfere).
In the end I have implemented this using writing a hidden file to the directory I want to limit access to, and checking the presence of this file based on the name in another process. This is not very fast and creates a race condition in the short time between the check and writing the file. Is there a better way?