python 25 线程池和指令系统

本文介绍了Python线程池的使用,包括线程等待、创建线程池、添加任务以及关闭线程池的方法。此外,还讲解了指令操作,如在Windows和Mac上执行Python程序、切换文件夹、创建虚拟环境以及使用pip管理Python包的基本操作。
摘要由CSDN通过智能技术生成

python 25 线程池和指令系统

一、线程等待
子线程 . join( ) — 阻塞当前线程直到指定线程任务完成。
from threading import Thread  #导入线程
from time import sleep  #导入等待时间
from datetime import datetime  #到时日期时间
from random import  randint    #导入随机数

def download(name):
    print(f'{name}开始下载:{datetime.now}')
    sleep(randint(2,7))    #
    print(f'{name}下载结束:{datetime.now}')

if __name__ == '__main__':
    t1 = Thread(target=download,args=('明日战绩',))
    t2 = Thread(target=download, args=('斗罗大陆',))
    t3 = Thread(target=download, args=('独行月球',))

    t1.start()
    t2.start()
    t3.start()

    #1.子线程对象.join() -   阻塞当前线程直到指定线程任务完成
    t1.join()
    t2.join()
    t3.join()
    print('==============下载结束===============')
import requests
from bs4 import BeautifulSoup
import csv
from concurrent.futures import ThreadPoolExecutor


def get_net_data(url: str):
    headers = {
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
    }
    proxies = {
        'http': '121.206.253.171:4512',
        'https': '121.206.253.171:4512'
    }
    response = requests.get(url, headers=headers, proxies=proxies)
    # return response.text
    analysis_data(response.text)


def analysis_data(html: str):
    # 解析数据
    soup = BeautifulSoup(html, 'lxml')
    all_film_div = soup.select('.grid_view>li>.item')
    all_data = []      #保存每一页所有电影
    for div in all_film_div:
        rank = div.select_one('.pic>em').text
        name = div.select_one('.title').text
        info = div.select_one('.bd>p').text.strip().split('\n')[-1].strip()
        # time, country, category = info.split('/')
        info_list = info.split('/')
        time = info_list[0]
        country = info_list[-2]
        category = info_list[-1]
        score = div.select_one('.rating_num').text
        comment_count = div.select('.star>span')[-1].text[:-3]
        intro_span = div.select_one('.inq')
        if intro_span:
            intro = intro_span.text
        else:
            intro = ''
        all_data.append([int(rank), name, score, time.strip(), country.strip(), category.strip(), comment_count, intro])
        films.append(all_data)
    # print(all_data)
    # writer.writerows(all_data)

if __name__ == '__main__':
    films = []  #保存所有列表

    f = open('file/电影.csv', 'w', encoding='utf-8', newline='')
    writer = csv.writer(f)
    writer.writerow(['排名', '电影名称', '评分', '上映时间', '国家', '类型', '评论数', '简介'])

    pool = ThreadPoolExecutor(10)
    for page in range(0, 251, 25):
        url = f'https://movie.douban.com/top250?start={page}&filter='
        pool.submit(get_net_data, url)

    pool.shutdown()
    # films.sort(key=lambda item:item[0][0])
    films.sort()
    for x in films:
        writer.writerows(x)
二、线程池

线程池是管理多个线程的工具

  • 线程池工作原理

先提前创建指定个数的线程,然后添加多个任务(任务数量>线程数量),让线程池中的线程去执行添加的所有任务,直到所有的任务都执行完(线程池中的每个线程都可能会执行多个任务)

2.1 创建线程池

ThreadPoolExecutor 创建线程池最大的值,注意,当线程很多的时候,只会创建3个线程
pool = ThreadPoolExecutor(100)

2.2 添加任务

线程池添加任务方式

方式1:一次添加一个任务 ---- submit(函数,实参1,实参2,实参3,…)
  • 注意:实参的数量由前面的函数在调用的时候,需要的实参来决定
方式2 :同时提交多个任务 ---- map(函数,参数序列)
  • 注意:使用map添加多个任务的时候,任务对应的函数,必须是有且只有一个参数对应的函数。

    2.3 关闭线程池

    线程池关闭后无法添加新的任务,并且hi阻塞当前线程等待整个线程池的任务完成。

    pool . shutdown()

  • 案例:使用多线程下载1000个电影

    方案1 :直接使用多线程下载1000个电影

    from threading import Thread,current_thread #current_thread 当前线程
    from time import sleep
    from datetime import datetime
    from concurrent.futures import ThreadPoolExecutor
    
    def download(name):
        print(f'{name}开始下载:{datetime.now()}',current_thread())
        sleep(2)
        print(f'{name}下载结束:{datetime.now()}')
    
    
    if __name__ == '__main__':
      
        num =   0
        for _ in range(4):
            ts = []
            for x in range(5):
                num += 1
                t = Thread(target=download,args=(f'电影{num}',))
                ts.append(t)
                t.start()
    
            for x in ts:
                x.join()
     ### 结果显示
    电影1开始下载:2022-08-19 21:50:59.406115 <Thread(Thread-1, started 269528)>
    电影2开始下载:2022-08-19 21:50:59.407115 <Thread(Thread-2, started 272252)>
    电影3开始下载:2022-08-19 21:50:59.407115 <Thread(Thread-3, started 262944)>
    电影4开始下载:2022-08-19 21:50:59.407115 <Thread(Thread-4, started 230448)>
    电影5开始下载:2022-08-19 21:50:59.407115 <Thread(Thread-5, started 268964)>
    电影2下载结束:2022-08-19 21:51:01.418595
    电影1下载结束:2022-08-19 21:51:01.418595
    电影5下载结束:2022-08-19 21:51:01.418595
    电影4下载结束:2022-08-19 21:51:01.418595
    电影3下载结束:2022-08-19 21:51:01.418595
    电影6开始下载:2022-08-19 21:51:01.419584 <Thread(Thread-6, started 168460)>
    电影7开始下载:2022-08-19 21:51:01.419584 <Thread(Thread-7, started 262512)>
    电影8开始下载:2022-08-19 21:51:01.419584 <Thread(Thread-8, started 234984)>
    电影9开始下载:2022-08-19 21:51:01.419584 <Thread(Thread-9, started 266792)>
    电影10开始下载:2022-08-19 21:51:01.420589 <Thread(Thread-10, started 269140)>
    电影9下载结束:2022-08-19 21:51:03.432116电影6下载结束:2022-08-19 21:51:03.432116电影8下载结束:2022-08-19 21:51:03.432116
    
    
    电影10下载结束:2022-08-19 21:51:03.432116电影7下载结束:2022-08-19 21:51:03.432116
    
    电影11开始下载:2022-08-19 21:51:03.433103 <Thread(Thread-11, started 267220)>
    电影12开始下载:2022-08-19 21:51:03.433103 <Thread(Thread-12, started 271940)>
    电影13开始下载:2022-08-19 21:51:03.433103 <Thread(Thread-13, started 271916)>
    电影14开始下载:2022-08-19 21:51:03.433103 <Thread(Thread-14, started 269500)>
    电影15开始下载:2022-08-19 21:51:03.434104 <Thread(Thread-15, started 250592)>
    电影14下载结束:2022-08-19 21:51:05.444016
    电影12下载结束:2022-08-19 21:51:05.444016
    电影11下载结束:2022-08-19 21:51:05.444016
    电影13下载结束:2022-08-19 21:51:05.444016
    电影15下载结束:2022-08-19 21:51:05.444016
    电影16开始下载:2022-08-19 21:51:05.444016 <Thread(Thread-16, started 244804)>
    电影17开始下载:2022-08-19 21:51:05.445018 <Thread(Thread-17, started 271268)>
    电影18开始下载:2022-08-19 21:51:05.445018 <Thread(Thread-18, started 264772)>
    电影19开始下载:2022-08-19 21:51:05.445018 <Thread(Thread-19, started 267192)>
    电影20开始下载:2022-08-19 21:51:05.445018 <Thread(Thread-20, started 270920)>
    电影16下载结束:2022-08-19 21:51:07.453546电影20下载结束:2022-08-19 21:51:07.453546电影19下载结束:2022-08-19 21:51:07.453546电影17下载结束:2022-08-19 21:51:07.453546
    
    电影18下载结束:2022-08-19 21:51:07.453546
    
    
    ===============完成==================
    

    方案2:使用线程池下载1000个电影

from threading import Thread,current_thread #current_thread 当前线程
from time import sleep
from datetime import datetime
from concurrent.futures import ThreadPoolExecutor

def download(name):
    print(f'{name}开始下载:{datetime.now()}',current_thread())
    sleep(2)
    print(f'{name}下载结束:{datetime.now()}')


if __name__ == '__main__':
    # 1. 创建线程池
    #ThreadPoolExecutor 创建线程池最大的值,注意,当线程很多的时候,只会创建3个线程
    pool = ThreadPoolExecutor(100)


    # 2.添加任务
    # 1)一次添加一个任务:submit(函数,实参1,实参2,实参3,...)
    #注意:实参的数量由前面的函数在调用的时候,需要的实参来决定
    pool.submit(download,'肖申克救赎')
    pool.submit(download, '霸王别姬')

    # 2)同时提交多个任务:map(函数,参数序列)
    # 注意:使用map添加多个任务的时候,任务对应的函数,必须是有且只有一个参数对应的函数
    pool.map(download,['三傻大闹好莱坞','星际穿越','沉默的羔羊','天天'])

    # 3 .关闭线程池
    # 线程池关闭后无法再添加新的任务,并且会阻塞当前线程等待整个线程池的任务完成
    pool.shutdown()
    print('===============完成==================')
    
### 结果显示
肖申克救赎开始下载:2022-08-19 21:55:34.872562 <Thread(ThreadPoolExecutor-0_0, started daemon 271484)>
霸王别姬开始下载:2022-08-19 21:55:34.873562 <Thread(ThreadPoolExecutor-0_1, started daemon 271996)>
三傻大闹好莱坞开始下载:2022-08-19 21:55:34.873562 <Thread(ThreadPoolExecutor-0_2, started daemon 252524)>
星际穿越开始下载:2022-08-19 21:55:34.874561 <Thread(ThreadPoolExecutor-0_3, started daemon 271944)>
沉默的羔羊开始下载:2022-08-19 21:55:34.874561 <Thread(ThreadPoolExecutor-0_4, started daemon 266488)>
天天开始下载:2022-08-19 21:55:34.874561 <Thread(ThreadPoolExecutor-0_5, started daemon 271904)>
天天下载结束:2022-08-19 21:55:36.880033沉默的羔羊下载结束:2022-08-19 21:55:36.880033霸王别姬下载结束:2022-08-19 21:55:36.880033
肖申克救赎下载结束:2022-08-19 21:55:36.880033

三傻大闹好莱坞下载结束:2022-08-19 21:55:36.880033

星际穿越下载结束:2022-08-19 21:55:36.880033
===============完成==================

三、指令操作

常见的指令操作
3.1 执行指令的工具:
  • Windows - 命令提示符(cmd) 、Mac - 终端

  • 运行python程序: - 运算程序的计算机必须先安装python环境

  • win: python py文件路径
    mac: python3 py文件路径

3.2 进入文件夹: cd
  1. cd 文件夹相对路径、文件夹绝对路径
  • 注意:如果是windows操作系统,cd操作
  • 如果要跨盘需要先切盘,然后再cd
    • 切盘方法:C:、E:、D:
  1. 查看当前文件夹的内容
    win: dir
    Mac:ls
3.3 用指令创建虚拟环境

第一步:找到一个用来放虚拟环境的文件夹
第二步:通过cd指令进入到存放虚拟环境的文件夹中

第三步:创建虚拟环境
python -m venv 虚拟环境名
python3 -m venv 虚拟环境名

第四步:激活虚拟环境
(mac) source 虚拟环境目录/bin/activate
(windows) 虚拟环境目录\ Scripts\activate.bat

第五步:退出虚拟环境
deactivate

3.4 常用pip指令(pip - Python包管理工具)
  • pip list - 查看当前环境已经安装过的所有的第三方库
  • pip install 第三方库名称 - 下载并且安装指定的第三方库
  • pip install 第三方库名称 -i 镜像地址 - 在指定的镜像地址中下载安装
  • pip install 第三方库名称==版本号 -i 镜像地址
  • pip install 第三方库名称1 第三方库名称2
  • pip freeze > 依赖文件名 - 生成依赖文件
    pip install -r 依赖文件路径 - 批量安装
  • pip uninstall 第三方库名称 - 卸载指定的第三方库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值