关于python线程池的四种实现方式
1. 使用Python标准库提供的ThreadPoolExecutor
Python标准库提供了concurrent.futures模块,其中含有ThreadPoolExecutor和ProcessPoolExecutor两个类。我们可以使用ThreadPoolExecutor来创建一个线程池。以下是示例代码:
import concurrent.futures
def task(n):
print('executing task %d' % n)
if __name__ == '__main__':
executor = concurrent.futures.ThreadPoolExecutor(max_workers=3)
for i in range(5):
executor.submit(task, i)
解释:
- 我们定义了一个名为“task”的函数来表示需要在线程池中执行的任务。
- 我们使用executor.submit()将任务提交到线程池中执行。
- 需要注意的是,在这个示例中executor.submit()执行时函数会被立即调用,因此我们可以看到executing task的输出混合在一起,这说明它们是并行执行的。
2. 使用Python标准库提供的Queue
除了ThreadPoolExecutor,在Python标准库的Queue模块中也提供了一些方法用于实现线程池。由于Python的多线程GIL限制,这种方式更适合于I/O密集的任务,而不是计算密集型任务。以下是示例代码:
import queue
import threading
def task(n):
print('executing task %d' % n)
def worker():
while True:
item = q.get()
if item is None:
break
task(item)
q.task_done()
if __name__ == '__main__':
num_worker_threads = 3
q = queue.Queue()
threads = []
for i in range(num_worker_threads):
t = threading.Thread(target=worker)
t.start()
threads.append(t)
for item in range(5):
q.put(item)
q.join()
for i in range(num_worker_threads):
q.put(None)
for t in threads:
t.join()
解释:
- 我们定义了两个函数:task表示任务本身,worker会被启动的线程,循环地从队列中获取任务并执行它。
- 我们创建了一个队列实例,并将线程添加到列表中以便后面统一管理。
- 我们将任务提交到队列中,并启动线程来获取它们。
- 最后我们等待队列中的所有项目都被处理完成(q.join()),并将每个线程都设置为退出循环(q.put(None))。
3. 使用第三方库提供的ThreadPool
许多第三方库也提供了线程池的实现。其中之一是multiprocessing库中的ThreadPool。这个库与标准库中的ThreadPoolExecutor非常相似,但提供了更多的选项。以下是示例代码:
from multiprocessing.pool import ThreadPool
def task(n):
print('executing task %d' % n)
if __name__ == '__main__':
pool = ThreadPool(processes=3)
tasks = range(5)
results = pool.map(task, tasks)
pool.close()
pool.join()
解释:
- 我们导入multiprocessing模块中的ThreadPool类,并定义了名为“task”的函数来表示要在线程池中执行的任务。
- 我们创建了一个ThreadPool实例,其“processes”变量设置为3。
- 然后我们将任务放入一个列表中,并使用pool.map()方法将它们批量提交到线程池中执行。
- 最后我们关闭线程池并等待所有任务完成。
4. 使用第三方库提供的Threadpool
另一个流行的线程池实现是Threadpool。该库提供了一些有用的功能,例如日志记录、任务优先级和任务超时等。以下是示例代码:
from threadpool import ThreadPool, makeRequests
def task(n):
print('executing task %d' % n)
if __name__ == '__main__':
pool = ThreadPool(3)
tasks = makeRequests(task, range(5))
[pool.putRequest(task) for task in tasks]
pool.wait()
解释:
- 我们首先导入Threadpool模块,并定义了名为“task”的函数来表示要在线程池中执行的任务。
- 我们创建了一个ThreadPool实例,max_threads变量设置为3。
- 然后我们使用makeRequests()方法创建一个由任务组成的列表。每个任务都是指向我们的“task”函数的指针,这个函数将任务编号打印到控制台。
- 最后,我们使用列表推导式将任务逐一提交到线程池中,然后等待所有任务完成。
总结:
以上就是关于python线程池的四种实现方式。其中,使用Python标准库提供的ThreadPoolExecutor可以说是最简单最直观的方式;使用Queue则可以将队列中的任务循环地提交到线程中;multiprocessing库提供的ThreadPool类与Python标准库中的ThreadPoolExecutor类似,但提供了更多的选项;Threadpool库提供了更多的功能,例如任务优先级和任务超时等。需要注意的是线程池的实现方式对于线程池的并发性能有很大的影响,不同的应用场景需要选择不同的实现方式。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:关于python线程池的四种实现方式 - Python技术站