title: Why threads will quit occasionally in my python program
body: <p>The program create a monitor thread with the function: thread_monitor. Then the monitor thread create hundreds of treads with fucntion: valid_proxy and a thread to counte the number of active threads every second.</p>
  
  <p>But after run several hours, I found the num of active threds is shrinking, from 500 to 472 for example. The longer the run time, the more the number of reduction. </p>
  
  <p>I don't know what's wrong in function valid_proxy to result abnormal thread exists. Could you help me to point the potential errors?</p>
  
  <p>All code is placed in: <a href="https://github.com/iaston/proxy_checker" rel="nofollow">https://github.com/iaston/proxy_checker</a> . Here are some code fragments.</p>
  
  <pre><code>import threading
  import time
  import requests
  import requests.exceptions
  import requests.adapters
  import datetime
  import queue
  import re
  
  def update_gui():
      while True:
          time.sleep(1)
          num_of_threads = 0
          for each_thread in threading.enumerate():
              if each_thread.name.find("Verify_Proxy_") == 0:
                  num_of_threads += 1                 
          print("\nNumber of running threads is %d.\n" % num_of_threads)
  
  
  def get_a_proxy():
      global g_b_stop, g_all_statu, g_proxy_queue, lock_get_proxy
      if g_b_stop:  
          return ""
      proxy_now = ""
      lock_get_proxy.acquire()
      try:
          while proxy_now == "":
              proxy_now = re.sub("[^\d:\.].+", "", str(g_proxy_queue.get(block=False)))
      except Exception:
          proxy_now = ""
      lock_get_proxy.release()
      return proxy_now
  
  
  def valid_proxy(check_site_info, success_try):
      global lock_valided_list, g_tree_proxies, g_all_statu, proxies_valided_list
      i_error_limit = success_try[1] - success_try[0]
      if i_error_limit &lt; 0:
          i_error_limit = 0
      i_error_now = 0
      proxy_now = get_a_proxy()
      while proxy_now != "":
          test_num = 0
          for each_check_site in check_site_info:  
  
              i_error_now = 0
              proxy_speed_recorder = {each_check_site: []}
              for iCounter in range(0, success_try[1]):  
                  test_num += 1
                  if (datetime.datetime.now() - g_gui_last_update_time).seconds &gt; g_gui_update_interval:
                      redraw_gui_event_finished.clear()
                  redraw_gui_event_finished.wait()  
                  try:
                      read_timeout = int(check_site_info[each_check_site]['timeout'])
                      connect_timeout = read_timeout / 2
                      if connect_timeout &lt; 2:
                          connect_timeout = 2
                      start_test_time = time.time()
                      req_headers = {
                          "User-Agent": "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0",
                          "Referer": check_site_info[each_check_site]['url']}
                      req_result = requests.get(check_site_info[each_check_site]['url'],
                                                timeout=(connect_timeout, read_timeout),
                                                proxies={'http': proxy_now, 'https': proxy_now}, headers=req_headers)
                      used_time_seconds = (time.time() - start_test_time) * 1000
  
                      html_result = req_result.text
                  except Exception as e:
                      used_time_seconds = -1
                      html_result = ""
                      print("\nError in proxy %s:\n%r" % (proxy_now, e))
                  if html_result.find(check_site_info[each_check_site]['keyword']) &lt; 0:
                      i_error_now += 1
                      if i_error_now &gt; i_error_limit:
                          print(('\nInvalided proxy: ' + proxy_now))
                          break  
                  else:
                      proxy_speed_recorder[each_check_site].append((iCounter, used_time_seconds))
  
                      if iCounter + 1 - i_error_now &gt;= success_try[0]:
                          break
              if i_error_now &gt; i_error_limit:
                  break  
          print("Proxy: " + proxy_now + " test number:" + str(test_num))
          if i_error_now &lt;= i_error_limit:
  
              all_used_time = 0
              all_test_time = 0
              for each_check_site in proxy_speed_recorder:
                  for each_test in proxy_speed_recorder[each_check_site]:
                      all_used_time += each_test[1]
                      all_test_time += 1
              avarge_time = round(all_used_time / all_test_time) if all_test_time != 0 else 0
              lock_valided_list.acquire()
              proxies_valided_list.append((proxy_now, avarge_time))
              try:
                  g_all_statu["text_proxy_valid_append"] += proxy_now + "&amp;" + str(avarge_time) + "\n"  
                  g_tree_proxies.add_data_treeview([(proxy_now, avarge_time)], skip_datebase=True)  
              except Exception as e2:
                  print("""g_all_statu["text_proxy_valid_append"] is wrong:\n""" + repr(e2))
              lock_valided_list.release()
          time.sleep(1)
          proxy_now = get_a_proxy()
      print("Finish, thread exit")
  
  
  def thread_monitor(check_site_info, success_try, th_num):
      for each_proxy in proxies_unvalided_list:
          g_proxy_queue.put(each_proxy)
  
      th_gui = threading.Thread(target=update_gui)
      th_gui.setDaemon(True)
      th_gui.start()
  
      ths_verify = []
      for iCounter in range(0, th_num):
          t = threading.Thread(target=valid_proxy, args=(check_site_info, success_try))
          t.setDaemon(True)
          t.setName("Verify_Proxy_" + str(iCounter))
          t.start()
          ths_verify.append(t)
  
      for iCounter in range(0, th_num):
          ths_verify[iCounter].join()
  
  
  thread_monitor(check_site_info, success_try, 500)
  </code></pre>