python线程池

python 线程池 ThreadPoolExecutor 的用法

两盒软妹~` 提交于 2019-12-06 03:18:28
 1. 线程池的基本用法 # coding: utf-8 from concurrent.futures import ThreadPoolExecutor import time def spider(page): time.sleep(page) print(f"crawl task{page} finished") return page with ThreadPoolExecutor(max_workers=5) as t: # 创建一个最大容纳数量为5的线程池 task1 = t.submit(spider, 1) task2 = t.submit(spider, 2) # 通过submit提交执行的函数到线程池中 task3 = t.submit(spider, 3) print(f"task1: {task1.done()}") # 通过done来判断线程是否完成 print(f"task2: {task2.done()}") print(f"task3: {task3.done()}") time.sleep(2.5) print(f"task1: {task1.done()}") print(f"task2: {task2.done()}") print(f"task3: {task3.done()}") print(task1.result()) #

python_多线程多进程

大憨熊 提交于 2019-12-05 07:01:08
进程就是多个资源的集合, 线程是包含在进程里面的,线程和线程直接是相对独立的 线程的优点 1.易于调度。 2.提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。 3.开销少。创建线程比创建进程要快,所需开销很少。 4.利于充分发挥多处理器的功能。通过创建多线程进程,每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。 def down_load(): time.sleep(5) print('运行完了') # threading.Thread(target=down_load,args=('name','id')#target是函数名,args是函数的参数没有可以不写 t1 = threading.Thread(target=down_load) t1.start()#启动线程 每个子线程都是在主线程里启动的子线程 ====================================================================================== 继承调用 class Test_thread(threading.Thread):#继承threading的Thread类 def __init__(self,num): threading.Thread.__init__(self

python线程池(转)

纵饮孤独 提交于 2019-12-04 23:23:31
ThreadPool: #! /usr/bin/env python # -*- coding: utf-8 -*- import threadpool import time def sayhello (a): print("hello: "+a) time.sleep(2) def main(): global result seed=["a","b","c"] start=time.time() task_pool=threadpool.ThreadPool(5) requests=threadpool.makeRequests(sayhello,seed) for req in requests: task_pool.putRequest(req) task_pool.wait() end=time.time() time_m = end-start print("time: "+str(time_m)) start1=time.time() for each in seed: sayhello(each) end1=time.time() print("time1: "+str(end1-start1)) if __name__ == '__main__': main()    Futures: #! /usr/bin/env python # -*- coding:

多种方法实现 python 线程池

谁都会走 提交于 2019-12-04 03:41:19
多种方法实现 python 线程池 最近在做一个爬虫相关的项目,单线程的整站爬虫,耗时真的不是一般的巨大,运行一次也是心累,,,所以,要想实现整站爬虫,多线程是不可避免的,那么python多线程又应该怎样实现呢?这里主要要几个问题(关于python多线程的GIL问题就不再说了,网上太多了)。 一、 既然多线程可以缩短程序运行时间,那么,是不是线程数量越多越好呢? 显然,并不是,每一个线程的从生成到消亡也是需要时间和资源的,太多的线程会占用过多的系统资源(内存开销,cpu开销),而且生成太多的线程时间也是可观的,很可能会得不偿失,这里给出一个最佳线程数量的计算方式: 最佳线程数的获取: 1、通过用户慢慢递增来进行性能压测,观察QPS(即每秒的响应请求数,也即是最大吞吐能力。),响应时间 2、根据公式计算:服务器端最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间) * cpu数量 3、单用户压测,查看CPU的消耗,然后直接乘以百分比,再进行压测,一般这个值的附近应该就是最佳线程数量。 二、为什么要使用线程池? 对于任务数量不断增加的程序,每有一个任务就生成一个线程,最终会导致线程数量的失控,例如,整站爬虫,假设初始只有一个链接a,那么,这个时候只启动一个线程,运行之后,得到这个链接对应页面上的b,c,d,,,等等新的链接,作为新任务,这个时候

python线程池

匿名 (未验证) 提交于 2019-12-02 22:51:30
线程池原理 1.控制线程,系统可以创建的线程数量有限,如果创建的线程资源数量不能够很好的加以限制,反而会导致系统性能的下降。 2.管理线程,对线程资源的重复利用。 3.提高响应速度:任务到达时,任务可以不需要等到线程创建就能立即执行。 线程池, 通俗的理解就是有一个池子,里面存放着已经创建好的线程资源,当有任务提交给线程池执行时,池中的某个线程就会主动执行该任务,执行完任务后该线程就会继续回到池子中等待下次任务的执行。下面我们就来看一下线程池的基本原理图,如下: 线程池的使用 concurrent.futures 线程池的基类是 concurrent.futures 模块中的 Executor,Executor 提供了两个子类,即 ThreadPoolExecutor 和 ProcessPoolExecutor,其中 ThreadPoolExecutor 用于创建线程池,而 ProcessPoolExecutor 用于创建进程池。 如果使用线程池/进程池来管理并发编程,那么只要将相应的 task 函数提交给线程池/进程池,剩下的事情就由线程池/进程池来搞定。 Exectuor 提供了如下常用方法: submit(fn, *args, **kwargs):将 fn 函数提交给线程池。*args 代表传给 fn 函数的参数,*kwargs 代表以关键字参数的形式为 fn 函数传入参数。

ThreadPoolExecutor线程池

筅森魡賤 提交于 2019-12-02 18:59:35
初识 Python 中已经有了 threading 模块,为什么还需要线程池呢,线程池又是什么东西呢?在介绍 线程同步的信号量机制 的时候,举得例子是爬虫的例子,需要控制同时爬取的线程数,例子中创建了20个线程,而同时只允许3个线程在运行,但是 20个线程都需要创建和销毁,线程的创建是需要消耗系统资源的 ,有没有更好的方案呢?其实只需要三个线程就行了,每个线程各分配一个任务,剩下的任务排队等待,当某个线程完成了任务的时候,排队任务就可以安排给这个线程继续执行。 这就是线程池的思想(当然没这么简单),但是自己编写线程池很难写的比较完美,还需要考虑复杂情况下的线程同步,很容易发生死锁。从 Python3.2 开始,标准库为我们提供了 concurrent.futures 模块,它提供了 ThreadPoolExecutor 和 ProcessPoolExecutor 两个类,实现了对 threading 和 multiprocessing 的进一步抽象(这里主要关注线程池),不仅可以帮我们 自动调度线程 ,还可以做到: 主线程可以获取某一个线程(或者任务的)的状态,以及返回值。 当一个线程完成的时候,主线程能够立即知道。 让多线程和多进程的编码接口一致。 实例 简单使用 from concurrent.futures import ThreadPoolExecutor import

深入分析 java 线程池的实现原理

坚强是说给别人听的谎言 提交于 2019-12-02 18:40:53
2019独角兽企业重金招聘Python工程师标准>>> 案例1 1、 Executors.newFixedThreadPool(10) 初始化一个包含10个线程的线程池executor; 2、通过 executor.execute 方法提交20个任务,每个任务打印当前的线程名; 3、负责执行任务的线程的生命周期都由Executor框架进行管理; ThreadPoolExecutor Executors是java线程池的工厂类,通过它可以快速初始化一个符合业务需求的线程池,如 Executors.newFixedThreadPool 方法可以生成一个拥有固定线程数的线程池。 其本质是通过不同的参数初始化一个ThreadPoolExecutor对象,具体参数描述如下: corePoolSize 线程池中的核心线程数,当提交一个任务时,线程池创建一个新线程执行任务,直到当前线程数等于corePoolSize;如果当前线程数为corePoolSize,继续提交的任务被保存到阻塞队列中,等待被执行;如果执行了线程池的prestartAllCoreThreads()方法,线程池会提前创建并启动所有核心线程。 maximumPoolSize 线程池中允许的最大线程数。如果当前阻塞队列满了,且继续提交任务,则创建新的线程执行任务,前提是当前线程数小于maximumPoolSize;

线程池参数的意义

江枫思渺然 提交于 2019-12-02 18:21:45
2019独角兽企业重金招聘Python工程师标准>>> 参考链接: https://www.cnblogs.com/jiangxiulian/p/7443983.html 1. corePoolSize: 核心线程数 缺省值为1 核心线程会一直存活,即使没有任务需要执行 当线程数小于核心线程数,即使有空闲线程,线程池也会优先创建新线程处理 设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭 2. queueCapacity: 任务队列容量(阻塞队列) 当核心线程数达到最大时,新任务会放在队列中排队等待执行 3. maxPoolSize: 最大线程数 当前线程数 >= corePoolSize, 且任务对列已满时,线程池会创建新线程来处理任务 当前线程数 = maxPoolSize, 且任务对列已满时, 线程池会拒绝处理任务而抛出异常 4. keepAliveTime: 线程空闲时间 当空闲时间达到keepAliveTime时,线程会退出,直到线程数量等于corePoolSize 如果allowCoreThreadTimeout=true, 则线程会退出,直到线程数量等于0 5. allowCoreThreadTimeout:允许核心线程超时 缺省是false 6. rejectedExecutionHandler: 任务拒绝处理器

day31总结

你离开我真会死。 提交于 2019-12-02 16:02:03
目录 线程队列 线程定时器 线程池和进程池 进程池和线程池--- concurrent.futures 什么时候用进程池还是什么时候用线程池? 线程池和信号量的区别 协程 什么是协程 什么样的协程是有意义的 为什么要有协程 gevent模块实现I/O监测和任务切换 线程队列 import queue q = queue.Queue(2) q.put('蔡启龙') # q.put('才气龙') print(q.get()) # 蔡启龙 q.task_done() q.join() q = queue.LifoQueue() # last in first out 先进后出队列---堆栈 q.put('123') q.put('456') print(q.get()) # 456 q = queue.PriorityQueue() # 优先级队列,可以根据优先级取数据 q.put('2') q.put('1') q.put('3') print(q.get()) # 1 # 通常放入的元组数据第一个值是int类型,数值小的先取出 线程定时器 import threading import time def task(): print('开始...') time.sleep(3) print('结束...') t = threading.Timer(5, task) #

python爬虫之线程池和进程池

天涯浪子 提交于 2019-11-30 03:19:40
python爬虫之线程池和进程池 一、需求   最近准备爬取某电商网站的数据,先不考虑代理、分布式,先说效率问题(当然你要是请求的太快就会被封掉,亲测,400个请求过去,服务器直接拒绝连接,心碎),步入正题。一般情况下小白的我们第一个想到的是for循环,这个可是单线程啊。那我们考虑for循环直接开他个5个线程,问题来了,如果有一个url请求还没有回来,后面的就干等,这么用多线程等于没用,到处贴创可贴。 二、性能考虑   确定要用多线程或者多进程了,那我们到底是用多线程还是多进程,有些人对多进程和多线程有一定的偏见,就因为python的GIL锁,下面我们说一下这两个东西的差别。 三、多线程:   一般情况下我们启动一个.py文件,就等于启动了一个进程,一个进程里面默认有一个线程工作,我们使用的多线程的意思就是在一个进程里面启用多个线程。但问题来了,为什么要使用多线程呢?我知道启动一个进程的时候需要创建一些内存空间,就相当于一间房子,我们要在这个房子里面干活,你可以想一个人就等于一个线程,你房子里面有10个人的空间跟有20个人的空间,正常情况下是不一样的,因为我们知道线程和线程之间默认是可以通信的(进程之间默认是不可以通信的,不过可以用技术实现,比如说管道)。可以多线程为了保证计算数据的正确性,所以出现了GIL锁,保证同一时间只能有一个线程在计算。GIL锁你可以基本理解为