Search code examples
pythonmultiprocessingsleepdaemon

python multiprocessing: sleep statement killed?


I have following code:

import multiprocessing, datetime

def Unit_Task_Function(Argument):

    print(f"Unit of work {Argument} starting {datetime.datetime.now().strftime('%Y-%m-%d : %H-%M-%S')}")
    sleep(2*random.random())
    print(f"Unit of work {Argument} ending {datetime.datetime.now().strftime('%Y-%m-%d : %H-%M-%S')}")    

if __name__ == "__main__":  # Allows for the safe importing of the main module
    __spec__ = "ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>)"

    print(f"There are {multiprocessing.cpu_count()} CPUs on this machine")

    max_para_processes_at_any_time = 5
    pool = multiprocessing.Pool(max_para_processes_at_any_time)


    iterable_arguments = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'M', 'N']

    results = pool.map_async(Unit_Task_Function, iterable_arguments)

    pool.close()
    pool.join()

And output is:

In [18]: run code.py
There are 8 CPUs on this machine
Unit of work A starting 2020-01-27 : 12-26-02
Unit of work B starting 2020-01-27 : 12-26-02
Unit of work C starting 2020-01-27 : 12-26-02
Unit of work D starting 2020-01-27 : 12-26-02
Unit of work E starting 2020-01-27 : 12-26-02
Unit of work F starting 2020-01-27 : 12-26-02
Unit of work G starting 2020-01-27 : 12-26-02
Unit of work H starting 2020-01-27 : 12-26-02
Unit of work M starting 2020-01-27 : 12-26-02
Unit of work N starting 2020-01-27 : 12-26-02

Why the 2nd print statement never accomplished? Is this related to so called "daemon" process? How to rewrite the code to make it work?


Solution

  • You are missing some imports. This causes import errors in the workers, which you cannot see. Import these:

    import random
    
    from time import sleep
    

    and you this output:

    There are 8 CPUs on this machine
    Unit of work A starting 2020-01-27 : 18-48-21
    Unit of work B starting 2020-01-27 : 18-48-21
    Unit of work C starting 2020-01-27 : 18-48-21
    Unit of work D starting 2020-01-27 : 18-48-21
    Unit of work E starting 2020-01-27 : 18-48-21
    Unit of work E ending 2020-01-27 : 18-48-21
    Unit of work F starting 2020-01-27 : 18-48-21
    Unit of work A ending 2020-01-27 : 18-48-22
    Unit of work G starting 2020-01-27 : 18-48-22
    Unit of work C ending 2020-01-27 : 18-48-22
    Unit of work H starting 2020-01-27 : 18-48-22
    Unit of work D ending 2020-01-27 : 18-48-22
    Unit of work M starting 2020-01-27 : 18-48-22
    Unit of work G ending 2020-01-27 : 18-48-22
    Unit of work N starting 2020-01-27 : 18-48-22
    Unit of work B ending 2020-01-27 : 18-48-22
    Unit of work M ending 2020-01-27 : 18-48-23
    Unit of work F ending 2020-01-27 : 18-48-23
    Unit of work N ending 2020-01-27 : 18-48-24
    Unit of work H ending 2020-01-27 : 18-48-24
    

    Hint: Use pool.map() first to see the error messages before switching to pool.map_async().

    Alternatively, supply an error callback function that re-raises the exception:

    def on_error(err):
            raise err
    
    results = pool.map_async(Unit_Task_Function, 
                             iterable_arguments,
                             error_callback=on_error)