[英]Why threads will quit occasionally in my python program
該程序使用函數thread_monitor創建一個監視線程。 然后,監視線程創建具有功能的數百個踏步:valid_proxy和一個線程,用於每秒計算活動線程的數量。
但是運行了幾個小時后,我發現活動線程的數量正在減少,例如從500減少到472。 運行時間越長,減少的次數越多。
我不知道在validate_proxy函數中導致存在異常線程的問題是什么。 您能幫我指出潛在的錯誤嗎?
所有代碼都位於: https : //github.com/iaston/proxy_checker 。 這是一些代碼片段。
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 < 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 > 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 < 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']) < 0:
i_error_now += 1
if i_error_now > 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 >= success_try[0]:
break
if i_error_now > i_error_limit:
break
print("Proxy: " + proxy_now + " test number:" + str(test_num))
if i_error_now <= 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 + "&" + 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)
我無法對您的函數valid_proxy
故障排除,因為它主要引用您未提供的代碼,而且我也不擅長。 但是,我可以告訴您,如果函數中的任何地方發生異常,它將導致線程退出。 如果您這樣做:
def forever_valid_proxy(*x,**y):
try:
valid_proxy(*x,**y)
except Exception:
pass
並替換該行:
t = threading.Thread(target=valid_proxy, args=(check_site_info, success_try))
有:
t = threading.Thread(target=forever_valid_proxy, args=(check_site_info, success_try))
線程數永遠不會減少。 我不知道這是您真正想要的程序還是需要的程序,但是您永遠不會看到線程數減少。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.