import time
import threading
-----------def sign():
----------- for i in range(0,3):
----------- print(f'唱第{i}====首歌')
----------- time.sleep(1)
-----------
-----------def dance():
----------- for i in range(0,3):
----------- print(f'跳第{i}====只舞')
----------- print("程序花费时间:",time.time()-start_time)
----------- time.sleep(1)
-----------
-----------
-----------##--start_time = time.time()
-----------##--sign()
-----------##--dance()
-----------##--print(time.time()-start_time)
-----------
-----------#把普通的函数对象转换成线程对象 只针对函数
-----------start_time = time.time()
-----------sign_thread = threading.Thread(target=sign) #target 函数任务目标
-----------print(sign_thread)
-----------#执行线程任务
-----------sign_thread.start()
-----------
-----------
-----------dance_thread = threading.Thread(target=dance) #target 函数任务目标
-----------print(dance_thread)
-----------#执行线程任务
-----------dance_thread.start()
多线程传参
def get(url,headers=None):
print(url)
time.sleep(3) ##阻塞
print(headers)
urls = ['https://www.baidu.com','https://www.guge.com','https://www.douban.com']
for url in urls:
get_thread = threading.Thread(
target = get, #传入函数的名字 转换对象
args=(url,), # args 指定函数的位置参数 如果只有一个 那么需要传入元组对象 就死加上逗号
kwargs = {'headers':{'user-agent':'Mozilla/5.0'}} ##传递了关键字参数
)
get_thread.start()
一个函数 只做一个功能 最理想的函数封装模式
发送请求
def send_requests(url):
response = requests.get(url)
return response
解析数据
def parse_data(data):
result = re.findall('',data,re.S)
保存数据
def save_data(filename,img_data): ##return None
with open ('img\' + filename , mode = 'wb' ) as f:
f.write(img_data)
print('正在保存---'+ title)
def main(url): ##总调度函数
html_data = send_requests(url=url).text
img_list = parse_data(html_data)
for img_url in img_list:
filename = img_url.split('/')[-1] ##文件名
img_data = send_requests(url=img_url).content
save_data(filename,img_data)
print("程序花费时间:",time.time()-start_time)
当主函数写完以后 一定要运行 主函数是否有问题 只有没问题 才可以构建多线程 否则出错找不到
测试主函数
main('')
start_time = time.time()
for page in range(0,3): #10页码 主线程 + 所有线程 = 11个任务
url = f'{page}'
main_thread = threading.Thread(target=main,args=(url,))
main_thread.start()
现在任务数据 不能用for循环实现 是不可以控制数量的
任务数量不是越多越好 是根据当前计算机性能实现 可以通过限制任务数量来解决 否则 丢包数据
敏感资源 全局变量 加锁 解锁
lock = threading.Lock()
with open('穷游.csv',mode='a',encoding='utf-8',newline='') as f:
csv_write = csv.writer(f)
for d in data:
--lock.acquire()加锁
csv_write.writerow(d)
--lock.release()解锁
lock = threading.Lock()
进程模块 ::: multiprocessing.Process
无法执行花费时间代码的 会报错
print("程序花费时间:",time.time()-start_time)
必须写在 if name == 'main':
解决丢包问题 启用线程池
import concurrent.futures ##导入了池子模块
if name == 'main':
#ThreadPoolExecutor 线程池对象
#ProcessPoolExecutor 进程池对象
# with concurrent.futures.ProcessPoolExecutor()
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
for i in range(10):
##@@@@@submit 向池子添加任务 参数按照位置传递 用逗号分隔开
executor.submit(thread_function,i)