Search code examples
pythonpython-2.7multiprocessingpython-multiprocessingmultiprocessing-manager

How python manager.dict() locking works:


A managers.dict() allow to share a dictionary across process and perform thread-safe operation. In my case each a coordinator process create the shared dict with m elements and n worker processes read and write to/from a single dict key.

Do managers.dict() have one single lock for the dict or m locks, one for every key in it?

Is there an alternative way to share m elements to n workers, other than a shared dict, when the workers do not have to communicate with each other?

Related python-manager-dict-is-very-slow-compared-to-regular-dict


Solution

  • After some tries I can say there is only one lock per managers dict. Here is the code that proves it:

    import time
    import multiprocessing as mp
    
    
    def process_f(key, shared_dict):
            values = [i for i in range(64 * 1024 * 1024)]
            print "Writing {}...".format(key)
            a = time.time()
            shared_dict[key] = values
            b = time.time()
            print "released {} in {}ms".format(key, (b-a)*1000)
    
    
    def main():
        process_manager = mp.Manager()
        n = 5
        keys = [i for i in range(n)]
        shared_dict = process_manager.dict({i: i * i for i in keys})
    
        pool = mp.Pool(processes=n)
    
        for i in range(n):
            pool.apply_async(process_f, (keys[i], shared_dict))
        time.sleep(20)
    
    
    if __name__ == '__main__':
        main()
    

    output:

    Writing 4...
    Writing 3...
    Writing 1...
    Writing 2...
    Writing 0...
    released 4 in 3542.7968502ms
    released 0 in 4416.22900963ms
    released 1 in 6247.48706818ms
    released 2 in 7926.97191238ms
    released 3 in 9973.71196747ms
    
    Process finished with exit code 0
    

    The increasing time for writing show the waiting which is happening.