python - 尽管守护进程设置为 True,但 Python 线程并没有停止
问题描述
我认为这是一个显而易见的问题,但我正在制作一个使用线程来测试代理的脚本,并且一旦找到一定数量的代理就应该停止。当我运行它时,如果满足条件,线程将停止生成输出,但程序不会关闭。我看过其他类似的问题,但似乎无法成功实施。将不胜感激任何指针。
import queue
import threading
import time
import urllib.request
class ThreadUrl(threading.Thread):
def __init__(self, queue, working_proxies):
threading.Thread.__init__(self)
self.queue = queue
self.working_proxies = working_proxies
def run(self):
while len(self.working_proxies)<5:
proxy = self.queue.get()
try:
proxy_handler = urllib.request.ProxyHandler({'http': proxy})
opener = urllib.request.build_opener(proxy_handler)
opener.addheaders = [('User-agent',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36')]
urllib.request.install_opener(opener)
req = urllib.request.Request('http://www.wikipedia.org')
sock=urllib.request.urlopen(req)
print(f'{proxy} works')
with appending_lock:
self.working_proxies.append(proxy)
except urllib.request.HTTPError as e:
print('Error code: ', e.code)
except Exception as detail:
print("ERROR:", detail)
self.queue.task_done()
def main(proxies, working_proxies):
for i in range(5):
t = ThreadUrl(queue,working_proxies)
t.daemon = True
t.start()
for proxy in proxies:
queue.put(proxy)
queue.join()
if __name__ == '__main__':
start = time.time()
appending_lock = threading.Lock()
proxies = [...list of proxies...]
working_proxies = []
queue = queue.Queue()
main(proxies, working_proxies)
print("Elapsed Time: %s" % (time.time() - start))
我是否使用了 daemon 属性错误,或者是否应该设置其他参数以确保线程停止?
解决方案
在浏览了文档和其他一些资源之后,我发现线程确实关闭了,但是 queue.join() 函数一直阻塞,直到队列被清空。由于如果线程在完成队列中的所有项目之前被终止,则不会发生这种情况,因此脚本继续运行。
所以,我已经覆盖了 queue.join() 看起来像这样:
queue = queue.Queue()
def waiter(queue):
while not queue.empty() and dead == False:
pass
queue.join = waiter
如果确定满足关闭条件,则在线程内访问“死”变量。在上面的代码中,将在 run() 函数的 while 循环中放置 'dead' 而不是 'len(self.working_proxies)<5'。每次将新项目附加到 self.working_proxies 时,脚本应检查是否满足终止条件,如果满足,则将 'dead' 设置为 True。
此外,'dead' 是一个全局变量,因此不需要将其传递给新的 waiter() 函数。
我敢肯定有一种更优雅的方法来解决这个问题,但同时这个方法应该可以解决问题。
推荐阅读
- function - 尝试使用与参数二相关的不正确或缺失的 INTERFACE 调用例程
- php - PHP Foreach 保存 ID
- google-sheets - 在复杂公式中添加另一个单元格的值
- ruby - 为什么会出现字符串/哈希比较失败?
- python-3.x - ACR122u/Python3/smartcard lib如何读取块
- java - 防止java打开浏览器
- python - 如何告诉 Python 从给定行开始执行代码
- regex - 正则表达式 - 查找不包含子字符串的多行字符串
- c# - 如何将查询转换为另一个接口的查询以基于该接口添加约束
- windows - 批处理文件:在两个带有特殊字符的字符串之间提取子字符串