what is a thread pool?
Many server applications, such as Web servers, database servers, file servers, and mail servers, are geared toward processing a large number of short tasks from some remote sources. A simplistic model for building server applications is to create a new service object whenever a request arrives, and then service the request in the new service object. However, when there are a large number of requests for concurrent access, it is expensive for the server to constantly create and destroy objects.
So one way to improve server efficiency is to minimize the number of objects created and destroyed, especially the resource-intensive creation and destruction of objects, which introduces the concept of "pooling".
The concept of "pooling" allows people to customize a certain amount of resources and then use them repeatedly instead of creating and destroying these resources frequently.
Thread pool is a technique for pre-creating threads。
These threads are all asleep, that is, they are started and do not consume the CPU, but only occupy a small amount of memory space.
When the request arrives, the buffer pool allocates an idle thread to the request, passes the request to the thread to run, and processes it.
When pre-created threads are running, that is, the thread pool is free to create a certain number of new threads to handle more requests.
When the system is idle, you can also remove a portion of a thread that has been in a deactivated state.
Thread Pool Considerations
Although the thread pool is a powerful mechanism for building multithreaded applications, using it is not without risk. When using the thread pool, pay attention to the relationship between thread pool size and performance, and pay attention to issues such as concurrency risk, deadlock, insufficient resources, and thread leaks.
1, thread pool size. Multithreaded applications not as many threads as possible, need to determine the size of the thread pool based on the hardware and software environment in which the system is running and the characteristics of the application itself.
In general, if the code is structured properly, the number of threads is appropriate for the number of CPUs.
If the thread is running, it can increase the size of the pool and, if necessary, use an adaptive algorithm to dynamically adjust the size of the thread pool to improve the efficient utilization of the CPU and the overall performance of the system.
2, concurrency error. Multi-threaded application to pay special attention to concurrency errors, to logically guarantee the correctness of the program, pay attention to avoid the occurrence of deadlock phenomenon.
3, thread leakage. This is a serious problem in the thread pool application, where a thread leak occurs when the task finishes and the thread fails to return to the pool.
Thread Pool essentials:
1, by judging the number of tasks to wait and the maximum value in the thread pool, take the minimum value to determine how many threads to open work
Like what:
The number of tasks is 3, the process pool is 20, then we just need to open 3 threads.
The number of tasks is 500, the process pool is 20, then we can only open 20 threads.
Take the minimum value
2, the implementation of the thread pool is running, there is a view of the function, look at the current thread of active threads is how much waiting for how much?
How many threads are in total, how many are waiting, how many are running
Role:
Easy to view current thread pool status
Can get to this after the thread has been in idle state
View status by: Context management to do, very nice point
3. Close the thread
Simple thread Pool Implementation
#!/usr/bin/env python#-*- coding:utf-8 -*-__author__ = ' luo_t ' Import Queueimport The idea of threadingimport time ' This simple example is through: 1, using the queue feature to create multiple thread objects in the queue 2, then I execute the code, go to the queue to get the thread! If the thread pool is available, take it directly. If the line constructor is not available, then wait. 3, thread execution is finished, return to thread pool "class threadpool (object): #创建线程池类 def __init__ (self, MAX_THREAD=20): #构造方法, set the maximum number of threads to 20 self.queue = Queue.queue (max_thread) #创建一个队列 for i in Xrange (max_thread): #循环把线程对象加入到队列中 Self.queue.put (Threading. Thread) #把线程的类名放进去, perform this queue def get_thread (self): #定义方法从队列里获取线程 Return self.queue.get () def add_thread (self): #定义方法在队列里添加线程 &nbsP; self.queue.put (Threading. Thread) Pool = threadpool (Def func) (arg,p): print arg time.sleep (2) p.add_thread () #当前线程执行完了, I'm adding a thread in the queue! For i in xrange (+): thread = pool.get_thread () # Thread pool 10 threads, each cycle take one! The default Queue.get () waits if there is no data in the queue. t = thread (target=func,args= (I,pool)) t.start () " Self.queue.put (Threading. Thread) added is that the class is not an object, in memory if the same class occupies only one portion of memory space and if the object is stored here, each time the new one has to open up a memory space in memory and if it is an object: The following statement can not be called so! For i in xrange (+): thread = pool.get_thread () t = thread (target=func,args= (I,pool)) t.start () by looking at the source code you know, in the thread's constructor:self.__args = args self.__target = target are private fields so that's what you should write FOR&NBSp;i in xrange (+): ret = pool.get_thread () ret._Thread__target = func ret._Thread__args = (I,pool) ret.start () "
The knowledge points that complex thread pooling needs to know
Knowledge Point ①
#!/usr/bin/env python#-*-coding:utf-8-*-import queueobj = object () #object也是一个类, I created an object OBJQ = Queue.queue () for I in Ran GE: Print ID (obj) #看萝卜号 q.put (obj) "This queue has 10 carrots (radish =obj), but these 10 carrots are just a projection. We put it in the queue for the For loop, does obj change? Is there a new space to open? Obviously no "
Knowledge Point ②
#!/usr/bin/env python#-*- coding:utf-8 -*-import contextlibimport threadingimport timeimport randomdoing = []def number (L2): while true: print len (L2) time.sleep (1) t = threading. Thread (target=number,args= (doing)) #开启一个线程, Print list per second, number of threads currently in Work T.start () # Add an adorner for the admin context @contextlib.contextmanagerdef show (li,iterm): li.append (iterm) yield ' yield Freeze This operation, go out, with Will catch, Then it executes the code block with the following, and when the code block under with executes, it returns to the code block that is not executed under yield! then it's done if the with code block is very time-consuming, is the length of the doing always 1, which means he's not done? We can get to the number that is being executed when he has finished with execution executes the subsequent code block of yield. After he was removed, it was 0! " li.remove (iterm) Def task (ARG): &nbsP; with show (doing,1): #通过with管理上下文进行切换 Print len (doing) time.sleep (Ten) # Wait 10 seconds Here you can use the random module to operate ~for i in range (: ) #开启20个线程执行 temp = threading. Thread (target=task,args= (i,)) temp.start () "Action: We want to record a working list such as a working thread I added to the doing list, If the work is done, remove it from the doing list. With this mechanism, you can get the number of threads that are currently executing
Implementation of thread pool
#!/usr/bin/env python#-*- coding:utf-8 -*-from queue import queueimport Contextlibimport threadingworkerstop = object () class threadpool: Workers = 0 threadfactory = threading. Thread currentthread = staticmethod (Threading.currentthread) def __init__ (Self, maxthreads=20, name=none): self.q = queue (0) #这里创建一个队列, if 0 means no limit, now this queue is a task self.max = maxthreads #定义最大线程数 self.name = name self.waiters = []# These two are used to count the self.working = [] #这两个是用来技术的 def start (self): #self .max Max Threads #q. Qisze (), Number of tasks needsize = self.q.qsize () while self.workers < min (self.max, needsize): #min (10,20) take minimum value #wokers默认为0 "workers = 0 " " For example: while self.workers < min (self.max, needsize): this loop, such as the maximum thread is 20, we have a task number of 10, take the minimum value of 10 each cycle of 1 threads, and workers self-increment 1, then the Loop 10 times, opened 10 threads workers = 10 , then the workers is not less than 10 will not open the thread, I have the maximum number of threads, you 10 threads to consume these 10 tasks go and it does not block, the creation of the thread will go to execute! each thread goes to execute the _worker method go ' self.startaworker () def startaworker (self): self.workers += 1 newthread = self.threadfactory (target=self._worker, name= ' Shuaige ') #创建一个线程并去执行_ Worker Method newthread.start () def Callinthread (self, func, *args, **kw): Self.callinthreadwithcallback (none, func, *args, **kw) def callinthreadwithcallback (SELF,&NBSP;ONRESULT,&NBSP;FUNC,&NBSP;*ARGS,&NBSP;**KW): o = (Func, args, kw, onresult) self.q.put (o) @contextlib. ContextManager def _workerstate (Self, statelist, workerthread): statelist.append (workerthread) try: yield finally: Statelist.remove (Workerthread) def _worker (self): ct = self.currentthread () o = self.q.get () #去队列里取任务, if you have a mission, OThere will be values, each task is a tuple, there are methods, parameters while o is not Workerstop: with self._workerstate (self.working, ct): #上下文切换 function, args, kwargs, onResult = o del o try: result = function (*args, **kwargs) success = True except: success = False if onresult is None: pass else: pass del function, args, kwargs if onresult is not none: try: onresult (success, Result) except: #context. Call (Ctx, log.err) pass del onResult, result with self._workeRstate (self.waiters, ct): #当线程工作完闲暇的时候, picking up tasks o = self.q.get () def stop (self ): #定义关闭线程方法 while self.workers: #循环workers值 self.q.put (WorkerStop) # Add a signal to the queue ~ self.workers -= 1 #workers值 -1 until all threads close Def show (ARG): import time time.sleep (1) print argpool = threadpool #创建500个任务, 500 tasks were added to the queue #每个任务都是一个元组 (method name, dynamic parameter, dynamic parameter, default is None) For i in range (+): pool.callinthread (show, i) Pool.start () #队列添加完成之后, open thread let the thread go to the queue one at a to get Pool.stop () #当上面的任务都执行完之后, The threads are waiting for the data to be in the queue! "' We're going to close all the threads and execute the Stop method, first workers this value is the current number of threads, we send a signal to the thread "Workerstop" in the work of the Threads: while o is not WorkerStop: if the thread gets to this value it does not execute, and then the thread is stopped while the loop waits for a Python garbage collection mechanism, Recovery. Then in self.workers -= 1 , then all the threads will stop after receiving this signal!!! Over~ ""
For more information, please refer to: http://www.cnblogs.com/wupeiqi/articles/4839959.html
Http://www.cnblogs.com/luotianshuai/p/5131001.html
This article from "Flat Light is true" blog, please be sure to keep this source http://ucode.blog.51cto.com/10837891/1766332
Python implements the thread pool