title: how to use tqdm with multithreading?
body: <p>I am trying to use tqdm to report the progress of each file downloads from three links, I wanted to use multithreading to download simultaneously from each link at the same time update the progress bar.
  But when I execute my script, there are multiple lines of progress bar it seems the thread are updating the tqdm progress bar the same time.
  I am asking how should I run multithreading for downloading the files while maintaining progress bar for each download without duplicated bars filling the entire screen?
  Here is my code.</p>
  <pre><code>import os
  import sys
  import requests
  from pathlib import Path
  from tqdm import tqdm
  from concurrent.futures import ThreadPoolExecutor as PE
  
  
  def get_filename(url):
      filename = os.path.basename(url)
      fname, extension = os.path.splitext(filename)
      if extension:
          return filename
      header = requests.head(url).headers
      if &quot;Location&quot; in header:
          return os.path.basename(header[&quot;Location&quot;])
      return fname
  
  
  def get_file_size(url):
      header = requests.head(url).headers
      if &quot;Content-Length&quot; in header and header[&quot;Content-Length&quot;] != 0:
          return int(header[&quot;Content-Length&quot;])
      elif &quot;Location&quot; in header and &quot;status&quot; not in header:
          redirect_link = header[&quot;Location&quot;]
          r = requests.head(redirect_link).headers
          return int(r[&quot;Content-Length&quot;])
  
  
  def download_file(url, filename=None):
      # Download to the Downloads folder in user's home folder.
      download_dir = os.path.join(Path.home(), &quot;Downloads&quot;)
      if not os.path.exists(download_dir):
          os.makedirs(download_dir, exist_ok=True)
      if not filename:
          filename = get_filename(url)
      file_size = get_file_size(url)
      abs_path = os.path.join(download_dir, filename)
      chunk_size = 1024
      with open(abs_path, &quot;wb&quot;) as f, requests.get(url, stream=True) as r, tqdm(
              unit=&quot;B&quot;,
              unit_scale=True,
              unit_divisor=chunk_size,
              desc=filename,
              total=file_size,
              file=sys.stdout
      ) as progress:
          for chunk in r.iter_content(chunk_size=chunk_size):
              data = f.write(chunk)
              progress.update(data)
  
  
  if __name__ == &quot;__main__&quot;:
      urls = [&quot;http://mirrors.evowise.com/linuxmint/stable/20/linuxmint-20-xfce-64bit.iso&quot;,
              &quot;https://www.vmware.com/go/getworkstation-win&quot;,
              &quot;https://download.geany.org/geany-1.36_setup.exe&quot;]
      with PE(max_workers=len(urls)) as ex:
          ex.map(download_file, urls)
  </code></pre>
  <p>I modified my code a bit, which i took from <a href="https://stackoverflow.com/questions/51601756/use-tqdm-with-concurrent-futures">Use tqdm with concurrent.futures?</a>.</p>
  <pre><code>    def download_file(url, filename=None):
      # Download to the Downloads folder in user's home folder.
      download_dir = os.path.join(Path.home(), &quot;Downloads&quot;)
      if not os.path.exists(download_dir):
          os.makedirs(download_dir, exist_ok=True)
      if not filename:
          filename = get_filename(url)
      # file_size = get_file_size(url)
      abs_path = os.path.join(download_dir, filename)
      chunk_size = 1024
      with open(abs_path, &quot;wb&quot;) as f, requests.get(url, stream=True) as r:
          for chunk in r.iter_content(chunk_size=chunk_size):
              f.write(chunk)
  
  
  if __name__ == &quot;__main__&quot;:
      urls = [&quot;http://mirrors.evowise.com/linuxmint/stable/20/linuxmint-20-xfce-64bit.iso&quot;,
              &quot;https://www.vmware.com/go/getworkstation-win&quot;,
              &quot;https://download.geany.org/geany-1.36_setup.exe&quot;]
      with PE() as ex:
          for url in urls:
              tqdm(ex.submit(download_file, url),
                   total=get_file_size(url),
                   unit=&quot;B&quot;,
                   unit_scale=True,
                   unit_divisor=1024,
                   desc=get_filename(url),
                   file=sys.stdout)
  </code></pre>
  <p>But the bar is not updating after i modified my code...</p>
  <p>My problem:<br />
  <img src="https://i.stack.imgur.com/YTbUV.png" alt="tqdm has duplicated progress bars" /></p>
  <p>I have no problem with concurrent download, but has problem implementing tqdm to update individual progress for each link, below is what I want to achieve:<br />
  <img src="https://i.stack.imgur.com/AxX7H.png" alt="ideally should have progress bar for each download." /></p>
  <p>I used one of the solution:</p>
  <pre><code>if __name__ == &quot;__main__&quot;:
  urls = [&quot;http://mirrors.evowise.com/linuxmint/stable/20/linuxmint-20-xfce-64bit.iso&quot;,
          &quot;https://www.vmware.com/go/getworkstation-win&quot;,
          &quot;https://download.geany.org/geany-1.36_setup.exe&quot;]
  
  with tqdm(total=len(urls)) as pbar:
      with ThreadPoolExecutor() as ex:
          futures = [ex.submit(download_file, url) for url in urls]
          for future in as_completed(futures):
              result = future.result()
              pbar.update(1)
  </code></pre>
  <p>But this is the result:
  <img src="https://i.stack.imgur.com/PEnmb.png" alt="enter image description here" /></p>