python -线程池

1.线程池-submit

python -线程池_第1张图片
python3.2版本之后才有的;

from concurrent.futures import  ThreadPoolExecutor

def job(num):
    # 需要执行的任务
    print("这是一个%s任务" %(num))
    return  "执行结果:%s" %(num)
if __name__ == '__main__':
    #  1. 实例化线城池对象,线城池里面包含5个线程执行任务;
    pool = ThreadPoolExecutor(max_workers=5)
    futures = []
    for i in range(1000):
        # 2.往线程池里面扔需要执行的任务, 返回的是一个对象(_base.Future()),jop函数名,i 函数job里的参数
        f1 = pool.submit(job, i)
        futures.append(f1)

    # 3.判断第一个任务是否执行结束;
    futures[0].done()

    # 获取任务的执行结果;
    print(futures[0].result())

python -线程池_第2张图片
线程池里面的线程越多越好吗?不是的
我们以之前爬虫ip城市的例子为例

import time
def timeit(f):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        res = f(*args, **kwargs)
        end_time = time.time()
        print("%s函数运行时间:%.2f" % (f.__name__, end_time - start_time))
        return res

    return wrapper


# python3.2版本之后才有的;
import threading
from concurrent.futures import ThreadPoolExecutor, wait
from urllib.request import urlopen


def get_area(ip):
    url = "http://ip-api.com/json/%s" % (ip)
    urlObj = urlopen(url)

    # 服务端返回的页面信息, 此处为字符串类型
    pageContent = urlObj.read().decode('utf-8')

    # 2. 处理Json数据
    import json
    # 解码: 将json数据格式解码为python可以识别的对象;
    dict_data = json.loads(pageContent)

    print("""
                        %s
    所在城市: %s
    所在国家: %s

    """ % (ip, dict_data['city'], dict_data['country']))


# 线程池里10个任务
@timeit
def use_ten_thread():
    #  1. 实例化线城池对象,线城池里面包含10个线程执行任务;
    pool = ThreadPoolExecutor(max_workers=10)

    futures = []
    for i in range(30):
        print("当前线程数:", threading.activeCount())
        ip = '12.13.14.%s' %(i+1)
        # 往线程池里面扔需要执行的任务, 返回的是一个对象(_base.Future()),
        f1 = pool.submit(get_area, ip)
        futures.append(f1)

    # 等待futures里面所有的子线程执行结束, 再执行主线程(join())
    wait(futures)


# 线城池里100个任务
@timeit
def use_hundred_thread():
    #  1. 实例化线城池对象,线城池里面包含100个线程执行任务;
    pool = ThreadPoolExecutor(max_workers=100)

    futures = []
    for i in range(30):
        print("当前线程数:", threading.activeCount())
        ip = '12.13.14.%s' %(i+1)
        # 往线程池里面扔需要执行的任务, 返回的是一个对象(_base.Future()),
        f1 = pool.submit(get_area, ip)
        futures.append(f1)

    wait(futures)

if __name__ == '__main__':
    use_ten_thread()
    use_hundred_thread()

2.线程池-map

map可以直接传值一个列表

import time


def timeit(f):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        res = f(*args, **kwargs)
        end_time = time.time()
        print("%s函数运行时间:%.2f" % (f.__name__, end_time - start_time))
        return res

    return wrapper


# python3.2版本之后才有的;
import threading
from concurrent.futures import ThreadPoolExecutor, wait
from urllib.request import urlopen


def get_area(ip):
    url = "http://ip-api.com/json/%s" % (ip)
    urlObj = urlopen(url)

    # 服务端返回的页面信息, 此处为字符串类型
    pageContent = urlObj.read().decode('utf-8')

    # 2. 处理Json数据
    import json
    # 解码: 将json数据格式解码为python可以识别的对象;
    dict_data = json.loads(pageContent)

    print("""
                        %s
    所在城市: %s
    所在国家: %s

    """ % (ip, dict_data['city'], dict_data['country']))


@timeit
def use_ten_thread():
    #  1. 实例化线城池对象,线城池里面包含10个线程执行任务;
    pool = ThreadPoolExecutor(max_workers=10)

    # futures = []
    # for i in range(30):
    #     print("当前线程数:", threading.activeCount())
    #     ip = '12.13.14.%s' %(i+1)
    #     # 往线程池里面扔需要执行的任务, 返回的是一个对象(_base.Future()),
    #     f1 = pool.submit(get_area, ip)
    #     futures.append(f1)
    #
    # # 等待futures里面所有的子线程执行结束, 再执行主线程(join())
    # wait(futures)

    # submit之前写的map用一句就可以
    ips = ['12.13.14.%s' % (ip + 1) for ip in range(30)]
    # map直接接收一个列表
    pool.map(get_area, ips)


@timeit
def use_hundred_thread():
    #  1. 实例化线城池对象,线城池里面包含100个线程执行任务;
    pool = ThreadPoolExecutor(max_workers=100)
    ips = ['12.13.14.%s' % (ip + 1) for ip in range(30)]
    pool.map(get_area, ips)



if __name__ == '__main__':
    use_ten_thread()
    use_hundred_thread()

线程池里10个线程时:用时129s
python -线程池_第3张图片python -线程池_第4张图片

线程池里100个任务时,最多执行30,因为循环只有30次,运行时间128s,与10个任务时几乎相同。

python -线程池_第5张图片
python -线程池_第6张图片
python -线程池_第7张图片

你可能感兴趣的:(python,多线程)