Search code examples
pythonpython-3.xclassmultiprocessingpool

Multiprocessing print command without structure


Today I wrote this post Multiprocessing Error with Results.

Now I modified this script to:

import multiprocessing

class class1():
    def classfunction1(self, a):
        self.x = a
        print("class 1")


class class2():
    def classfunction2(self, a):
        self.y = a
        print("class 2")

def test(i):
    print("I'm in the Testfunction")
    b = i * class1.x * class2.y

    return b

def init():  # added
    print("I'm in the Initfunction")
    global class1, class2
    class1 = class1()
    class2 = class2()
    x = 1
    y = 2
    class1.classfunction1(x)
    class2.classfunction2(y)

if __name__ == "__main__":
    init()  # explicit call here
    print("This variable is callable", class1.x)
    print("And this one is also callable", class2.y)
    counter = []
    for i in range(10):
        counter.append(i)
    pool = multiprocessing.Pool(initializer=init, processes=4)  # implicit call
    results = pool.imap(test, counter)
    pool.close()
    pool.join()
    resultslist = list(results)
    print(resultslist)

I inserted some print-commands to the classes. But the result is a structureless printing, like this:

I'm in the Initfunction
class 1
class 2
This variable is callable 1
And this one is also callable 2
I'm in the Initfunction
class 1
class 2
I'm in the Testfunction
I'm in the Testfunction
I'm in the Testfunction
I'm in the Testfunction
I'm in the Testfunction
I'm in the Testfunction
I'm in the Testfunction
I'm in the Testfunction
I'm in the Testfunction
I'm in the Testfunction
I'm in the Initfunction
class 1
class 2
I'm in the Initfunction
class 1
class 2
I'm in the Initfunction
class 1
class 2
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

The prints in the classes I just want once... Only the text "I'm in the Testfunction" I want multiple (10 times).

Has anyone possibly a solution?


Solution

  • As I (poorly) tried to explain in a comment (now deleted), you can do it by adding an optional argument with a default value to the init() function (and to the class methods):

    from __future__ import print_function
    import multiprocessing
    import sys
    
    sys_print = print  # save built-in print function before replacement is defined
    
    def print(*args, **kwargs):
        """Replacement for built-in that flushes output stream after each call."""
        sys_print(*args, **kwargs)
        stdout = kwargs.get('file', sys.stdout)
        stdout.flush()  # force any buffered output to be displayed
    
    class class1():
        # note addition of optional argument with default value
        def classfunction1(self, a, notify=False):
            self.x = a
            if notify: print("class 1")
    
    class class2():
        # note addition of optional argument with default value
        def classfunction2(self, a, notify=False):
            self.y = a
            if notify: print("class 2")
    
    def test(i):
        print("I'm in the Testfunction")
        b = i * class1.x * class2.y
    
        return b
    
    def init(notify=False):  # note addition of optional argument with default value
        if notify: print("I'm in the Initfunction")
        global class1, class2
        class1 = class1()
        class2 = class2()
        x = 1
        y = 2
        class1.classfunction1(x, notify)
        class2.classfunction2(y, notify)
    
    if __name__ == "__main__":
        init(True)  # override default arg in this explicit call
        print("This variable is callable", class1.x)
        print("And this one is also callable", class2.y)
        counter = list(range(10))
        pool = multiprocessing.Pool(initializer=init, processes=4)  # implicit calls
        results = pool.imap(test, counter)
        pool.close()
        pool.join()
        resultslist = list(results)
        print(resultslist)
    

    Output:

    I'm in the Initfunction
    class 1
    class 2
    This variable is callable 1
    And this one is also callable 2
    I'm in the Testfunction
    I'm in the Testfunction
    I'm in the Testfunction
    I'm in the Testfunction
    I'm in the Testfunction
    I'm in the Testfunction
    I'm in the Testfunction
    I'm in the Testfunction
    I'm in the Testfunction
    I'm in the Testfunction
    [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]