python(13)线程池:threading

先上代码:

 1 pool = threadpool.ThreadPool(10) #建立线程池,控制线程数量为10
 2 reqs = threadpool.makeRequests(get_title, data, print_result) #构建请求,get_title为要运行的函数,data为要多线程执行函数的参数
 3                                                               #最后这个print_result是可选的,是对前两个函数运行结果的操作
 4 [pool.putRequest(req) for req in reqs] #多线程一块执行
 5 pool.wait() #线程挂起,直到结束
1 [pool.putRequest(req) for req in reqs] #相当于如下两行代码
2 for req in requests:
3   pool.putRequest(req)  

示例代码:

 1 import threadpool
 2 import time,random
 3 import Queue
 4
 5 def hello1(str):
 6     time.sleep(2)
 7     return str
 8
 9 def print_ret(request, result):
10     print "the result is %s %r\n" % (request.requestID, result)
11
12
13 def deal_task(pool):
14     try:
15         pool.poll(True)
16     except Exception, e:
17         print str(e)
18
19 #lst = [1,2,3,4,5,6,7]
20 q = Queue.Queue()
21 for i in range(100):
22     q.put(i)
23
24 lst = [q.get() for i in range(q.qsize())]
25
26 pool = threadpool.ThreadPool(20)
27 requests = threadpool.makeRequests(hello1, lst, print_ret)
28 for req in requests:
29     pool.putRequest(req)
30     #deal_task(pool)
31
32 pool.wait()

什么是线程池?

诸如web服务器、数据库服务器、文件服务器和邮件服务器等许多服务器应用都面向处理来自某些远程来源的大量短小的任务。构建服务器应用程序的一个过于简 单的模型是:每当一个请求到达就创建一个新的服务对象,然后在新的服务对象中为请求服务。但当有大量请求并发访问时,服务器不断的创建和销毁对象的开销很 大。所以提高服务器效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁,这样就引入了“池”的概念,“池”的概念使 得人们可以定制一定量的资源,然后对这些资源进行复用,而不是频繁的创建和销毁。

线程池是预先创建线程的一种技术。线程池在还没有任务到来之前,创建一定数量的线程,放入空闲队列中。这些线程都是处于睡眠状态,即均为启动,不消耗 CPU,而只是占用较小的内存空间。当请求到来之后,缓冲池给这次请求分配一个空闲线程,把请求传入此线程中运行,进行处理。当预先创建的线程都处于运行 状态,即预制线程不够,线程池可以自由创建一定数量的新线程,用于处理更多的请求。当系统比较闲的时候,也可以通过移除一部分一直处于停用状态的线程。

线程池的注意事项

虽然线程池是构建多线程应用程序的强大机制,但使用它并不是没有风险的。在使用线程池时需注意线程池大小与性能的关系,注意并发风险、死锁、资源不足和线程泄漏等问题。

(1)线程池大小。多线程应用并非线程越多越好,需要根据系统运行的软硬件环境以及应用本身的特点决定线程池的大小。一般来说,如果代码结构合理的话,线程数目与CPU 数量相适合即可。如果线程运行时可能出现阻塞现象,可相应增加池的大小;如有必要可采用自适应算法来动态调整线程池的大小,以提高CPU 的有效利用率和系统的整体性能。

(2)并发错误。多线程应用要特别注意并发错误,要从逻辑上保证程序的正确性,注意避免死锁现象的发生。

(3)线程泄漏。这是线程池应用中一个严重的问题,当任务执行完毕而线程没能返回池中就会发生线程泄漏现象。

简单线程池的设计

一个典型的线程池,应该包括如下几个部分:
1、线程池管理器(ThreadPool),用于启动、停用,管理线程池
2、工作线程(WorkThread),线程池中的线程
3、请求接口(WorkRequest),创建请求对象,以供工作线程调度任务的执行
4、请求队列(RequestQueue),用于存放和提取请求
5、结果队列(ResultQueue),用于存储请求执行后返回的结果

线程池管理器,通过添加请求的方法(putRequest)向请求队列(RequestQueue)添加请求,这些请求事先需要实现请求接口,即传递工作
函数、参数、结果处理函数、以及异常处理函数。之后初始化一定数量的工作线程,这些线程通过轮询的方式不断查看请求队列(RequestQueue),只
要有请求存在,则会提取出请求,进行执行。然后,线程池管理器调用方法(poll)查看结果队列(resultQueue)是否有值,如果有值,则取出,
调用结果处理函数执行。通过以上讲述,不难发现,这个系统的核心资源在于请求队列和结果队列,工作线程通过轮询requestQueue获得人物,主线程
通过查看结果队列,获得执行结果。因此,对这个队列的设计,要实现线程同步,以及一定阻塞和超时机制的设计,以防止因为不断轮询而导致的过多cpu开销。

线程池实现原理图

时间: 2024-09-29 20:31:04

python(13)线程池:threading的相关文章

《java.util.concurrent 包源码阅读》13 线程池系列之ThreadPoolExecutor 第三部分

这一部分来说说线程池如何进行状态控制,即线程池的开启和关闭. 先来说说线程池的开启,这部分来看ThreadPoolExecutor构造方法: public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecut

并发编程 13—— 线程池 之 整体架构

Java并发编程实践 目录 并发编程 01—— ConcurrentHashMap 并发编程 02—— 阻塞队列和生产者-消费者模式 并发编程 03—— 闭锁CountDownLatch 与 栅栏CyclicBarrier 并发编程 04—— Callable和Future 并发编程 05—— CompletionService : Executor 和 BlockingQueue 并发编程 06—— 任务取消 并发编程 07—— 任务取消 之 中断 并发编程 08—— 任务取消 之 停止基于线

python自定义线程池

1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 #!/usr/bin/env python 4 # -*- coding:utf-8 -*- 5 6 import queue 7 import threading 8 import contextlib 9 import time 10 11 StopEvent = object() 12 13 14 class ThreadPool(object): 15 16 def __init__(s

python之线程池

#!/user/bin/evn python # -*- coding:utf-8 -*- import threading import queue,time ''' 线程池的思路: 将任务依次放在队列里面 然后从队列取出任务交给线程执行 ''' stopEvent=object()#任务完了的标志---下面我们将任务包封装到元组中 class ThreadPool(object): def __init__(self,max_num): #创建队列 self.q=queue.Queue()

Python之路【第八篇】python实现线程池

线程池概念 什么是线程池?诸如web服务器.数据库服务器.文件服务器和邮件服务器等许多服务器应用都面向处理来自某些远程来源的大量短小的任务.构建服务器应用程序的一个过于简单的模型是:每当一个请求到达就创建一个新的服务对象,然后在新的服务对象中为请求服务.但当有大量请求并发访问时,服务器不断的创建和销毁对象的开销很大.所以提高服务器效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁,这样就引入了“池”的概念,“池”的概念使得人们可以定制一定量的资源,然后对这些资源

python实现线程池

什么是线程池?     诸如web服务器.数据库服务器.文件服务器和邮件服务器等许多服务器应用都面向处理来自某些远程来源的大量短小的任务.构建服务器应用程序的一个过于简单的模型是:每当一个请求到达就创建一个新的服务对象,然后在新的服务对象中为请求服务.但当有大量请求并发访问时,服务器不断的创建和销毁对象的开销很大.所以提高服务器效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁,这样就引入了"池"的概念,"池"的概念使得人们可以定制

《Python》线程池、携程

一.线程池(concurrent.futures模块) #1 介绍 concurrent.futures模块提供了高度封装的异步调用接口 ThreadPoolExecutor:线程池,提供异步调用 ProcessPoolExecutor: 进程池,提供异步调用 Both implement the same interface, which is defined by the abstract Executor class. #2 基本方法 #submit(fn, *args, **kwargs

[python] ThreadPoolExecutor线程池 python 线程池

初识 Python中已经有了threading模块,为什么还需要线程池呢,线程池又是什么东西呢?在介绍线程同步的信号量机制的时候,举得例子是爬虫的例子,需要控制同时爬取的线程数,例子中创建了20个线程,而同时只允许3个线程在运行,但是20个线程都需要创建和销毁,线程的创建是需要消耗系统资源的,有没有更好的方案呢?其实只需要三个线程就行了,每个线程各分配一个任务,剩下的任务排队等待,当某个线程完成了任务的时候,排队任务就可以安排给这个线程继续执行. 这就是线程池的思想(当然没这么简单),但是自己编

Python菜鸟之路:Python基础-线程池注释

import sys import threading import Queue import traceback # 定义一些Exception,用于自定义异常处理 class NoResultsPending(Exception): """All works requests have been processed""" pass class NoWorkersAvailable(Exception): """N

Python的线程池

#!/usr/bin/env python # -*- coding: utf-8 -*- """ concurrent 用于线程池和进程池编程而且更加容易,在Python3.2中才有. """ import sys from concurrent.futures import ThreadPoolExecutor, as_completed, wait from multiprocessing import Manager Manager().