7

I have a script where I'm loading a file which takes a while because there is quite much data to read and to prevent the user from terminating the process I want to show some kind of loading indication. I thought this was a good opportunity to learn how to use the multiprocessing module so I wrote this example to test the module:

import time, multiprocessing

def progress():
    delay = 0.5
    while True:
        print "Loading.",
        time.sleep(delay)
        print "\b.",
        time.sleep(delay)
        print "\b.",
        time.sleep(delay)
        print "\r                        \r",

    return

def loader(filename, con):
    # Dummy loader
    time.sleep(5)
    con.send(filename)
    con.close()
    return

if __name__ == "__main__":
    parrent_con, child_con = multiprocessing.Pipe()
    filename = "main.key"

    p1 = multiprocessing.Process(target=progress)
    p2 = multiprocessing.Process(target=loader, args=(filename, child_con))

    p1.start()
    p2.start()

    data = parrent_con.recv()
    p1.terminate()
    print "\n", data

It works as I expect when I run it in windows cmd, it prints "Loading" and sequentially adds dots until the loader is complete. But in unix where I need it to work I don't get any output from progress function, process p1.

2
  • 2
    I don't know the pythonic method, but the problem is buffering. By default, Linux buffers each line, and since you are not sending \n, nothing gets updated. Try running the program with \n instead of \r. If that works, you need to figure out how to disable line buffering in python. In C, the command is setvbuf Commented May 15, 2015 at 6:58
  • I was thinking of buffering as well. Does it work if you put some sys.stdout.flush() around? Commented May 15, 2015 at 7:00

1 Answer 1

4

Just as Mark and Dacav suggested, buffering is the problem. Here are some possible solutions:

  • Using python -u to run the script

    python -u will unbuffer stdout and stderr. This is the easiest solution if it's acceptable to you.

  • Using sys.stdout.flush

    sys.stdout.flush will flush the stdout from buffer.

    delay = 0.5
    while True:
        print("Loading."),
        sys.stdout.flush()
        time.sleep(delay)
        print("\b."),
        sys.stdout.flush()
        time.sleep(delay)
        print("\b."),
        sys.stdout.flush()
        time.sleep(delay)
        print("\r                        \r"),
        sys.stdout.flush()
    return
    
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.