问题描述: python3.7 学习多线程的时候,一个问题,打印出来的结果为什么是这样的?
# -*- coding=utf-8 -*-
import threading
from queue import Queue
from lxml import etree
import requests
import json
class ThreadCrawl(threading.Thread):
def __init__(self, thread_name, page_queue, data_queue):
# threading.Thread.__init__(self) # 如果继承多个类, 前面就要修改了
super(ThreadCrawl, self).__init__() # 这里调用自己, 只继承一个的话,两个就没差
self.thread_name = thread_name # 线程名
self.page_queue = page_queue # 页码队列
self.data_queue = data_queue # 数据队列
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"
}
def run(self): # 队列为空的话,中止操作
print("现在启动的线程名字是: " + self.thread_name)
while not CRAWL_EXIT:
try:
'''
一:队列为空,且 block 值为 True (默认值为 True) ,就会进入阻塞状态,直到队列有新的数据 (不会结束)
二:队列为空,block 值为 False, 报 Queue.empty() 异常
这里只放了 10 个页,所以选择第二种
'''
page = self.page_queue.get(False) # 取出一个数字,FIFO ,先进先出:
print(page)
url = "https://www.qiushibaike.com/8hr/page/" + str(page) + "/"
content = requests.get(url, headers=self.headers)
self.data_queue.put(content) # 把采集的源码放入 数据队列
except Exception as e:
print("出错了: " + e)
pass
CRAWL_EXIT = False # 采集退出信号
PARSE_EXIT = False # 解析信号
def main():
page_queue = Queue(10) # 页码的队列, 表示 10 个页面
for i in range(1, 11): # 放入 1-10 的数字,FIFO 先进先出
page_queue.put(i)
data_queue = Queue() # 参数为空表示不限制
crawl_list = ["采集线程1号", "采集线程2号", "采集线程3号"] # 三个采集线程的名字
thread_crawl = [] # 存储三个采集线程
for thread_name in crawl_list:
thread = ThreadCrawl(thread_name, page_queue, data_queue)
thread.start()
thread_crawl.append(thread)
while not page_queue.empty(): # pageQueue 队列为空,也就是等待之前操作执行完毕
print(str(page_queue.get()) + "队列还没有空")
global CRAWL_EXIT # 如果采集线程为空(page_queue), 采集线程退出循环
CRAWL_EXIT = True
print("page_queue 为空")
'''
潜在线程
守护线程: 主线程结束,子线程也结束
所以下面创建非守护线程, 手动加一个阻塞状态
'''
for thread in thread_crawl:
print("等待线程 " + str(thread.thread_name) + " 的执行完成")
thread.join()
# 最后是主线程退出
if __name__ == "__main__":
main()
为什么 1 , 2 , 4 , 7 没有正常 打印,字都省掉了?
问题解决: 待解决