Vingtoft
Vingtoft

Reputation: 14606

Python: Print to separate bash line for every thread, in a multithread application

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

Upvotes: 5

Views: 2260

Answers (2)

Tony Babarino
Tony Babarino

Reputation: 3405

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()

Upvotes: 5

dvaergiller
dvaergiller

Reputation: 815

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.

Upvotes: 1

Related Questions