5

I saw in this post that its easy to print on the same line (overwriting the previous content) the following way:

print "Downloading " + str(a) " file of " + str(total),

(note the comma at the end). This would result in

>>> Downloading 1 file of 20

and each time the print is executed, the same line is updated.

This works well in a single threaded application, but it does not work with multiple threads.

How can multiple threads print to its own line in the terminal in python 2.7?

The desired result would look something like this:

>>> Thread 1: Downloading 11 file of 20
>>> Thread 2: Downloading 4 file of 87
>>> Thread 3: Downloading 27 file of 32
>>> Thread 4: Downloading 9 file of 21
Community
  • 1
  • 1
Vingtoft
  • 13,368
  • 23
  • 86
  • 135

2 Answers2

5

You can achieve that using curses module.

The curses module provides an interface to the curses library, the de-facto standard for portable advanced terminal handling.

Each thread can edit its global string variable and You can display those variables in separate lines using curses in the main thread.

Check the example code that I've written, it does what You want:

from threading import Thread
import curses
import time

#global variables
line_thread_1 = 0 
line_thread_2 = 0
end_1 = False
end_2 = False

def thread1():
    global line_thread_1
    global end_1
    for i in xrange(10):
        time.sleep(0.5)
        line_thread_1 += 1
    end_1 = True

def thread2():
    global line_thread_2
    global end_2
    for i in xrange(10):
        time.sleep(0.25)
        line_thread_2 += 1
    end_1 = True

thread1 = Thread(target=thread1)
thread2 = Thread(target=thread2)
thread1.start()
thread2.start()

stdscr = curses.initscr()
while not (end_1 or end_2):
    stdscr.erase()
    stdscr.addstr('>>> Thread 1: ' + str(line_thread_1) + ' of 10\n')
    stdscr.addstr('>>> Thread 2: ' + str(line_thread_2) + ' of 10\n')
    stdscr.refresh()
    time.sleep(1)
curses.endwin()
Tony Babarino
  • 3,355
  • 4
  • 32
  • 44
  • Shouldn't you avoid using global vars in multi threaded applications? Thanks for the answer though – Vingtoft Apr 15 '16 at 09:25
  • 1
    Well if many threads operate on the same global var, a race-condition can occur and that requires additional treatment - for example using locks. But in this simple case every thread operate on its own variables, so nothing bad can happen. – Tony Babarino Apr 15 '16 at 09:47
1

The comma in the end of the line only prevents a newline character from being printed in the end of the string. It does not edit the previously printed line when you call it again. This has nothing to do with threading. Look at this:

print "a ",
print "b ",
print "c"
print "d ",
print "e ",
print "f"

The output of that will be:

a b c
d e f

Because each time there is a comma in the end, the next print call will only add to the same line as before.

If you would like to control where things are printed maybe cursor movement could be useful: http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html

You can also use the curses library if you need something more complicated.

dvaergiller
  • 795
  • 3
  • 11