Home > Mobile >  How to prevent tqdm from printing progress bar in newline while multithreading?
How to prevent tqdm from printing progress bar in newline while multithreading?

Time:09-18

I was messing around with the tqdm module and wanted to run simultaneous progress bars, so i made Thread objects as below

from tqdm import tqdm
import time
from threading import Thread

def func1():
    for i in tqdm(range(20)):
        time.sleep(0.1)

def func2():
    for j in tqdm(range(20)):
        time.sleep(0.3)

t1 = Thread(target=func1)
t2 = Thread(target=func2)

t1.start()
t2.start()

t2.join()
t1.join()

print('Completed')

The output starts withStarting ouput

But when thread t2 ends, it exchanges position with the bar display of t1 and t1 runs till it ends.

I don't want the bars to exchange positions

I tried interchanging the positions of lines of starting and joining of threads but it leads to re printing of t1 bar once t2 finishes like this messed up output

To analyse these problems i would recommend trying running these codes for yourself.

Can someone tell me why these both things are happening and how to fix it ?

CodePudding user response:

One solution could be updating all bars in separate thread (using Queue to get which bar should be updated next):

import time
import queue
from tqdm import tqdm
from threading import Thread

bars_queue = queue.Queue()


def func1():
    for i in range(20):
        bars_queue.put_nowait(0)  # update bar 0
        time.sleep(0.1)


def func2():
    for j in range(20):
        bars_queue.put_nowait(1)  # update bar 1
        time.sleep(0.3)


def bars_handler():
    bars = [tqdm(total=20, position=i) for i in range(2)]
    while True:
        i = bars_queue.get()  # which bar should I update next?
        bars[i].update()
        bars[i].refresh()


bars_thread = Thread(target=bars_handler, daemon=True) # daemon=True so we don't have to use .join()
bars_thread.start()

t1 = Thread(target=func1)
t2 = Thread(target=func2)

t1.start()
t2.start()

t2.join()
t1.join()

print("{}Completed".format("\n" * 2))

Prints correctly the bars:

100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 20/20 [00:01<00:00, 10.09it/s]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 20/20 [00:05<00:00,  3.33it/s]
Completed
  • Related