python多线程之threading、ThreadPoolExecutor.map
背景:
(多线程执行同一个函数任务)某个应用场景需要从数据库中取出几十万的数据时,需要对每个数据进行相应的操作。逐个数据处理过慢,于是考虑对数据进行分段线程处理:
方法一:使用threading模块
代码:
# -*- coding: utf-8 -*-
import math
import random
import time
from threading import Thread _result_list = [] def split_df():
# 线程列表
thread_list = []
# 需要处理的数据
_l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 每个线程处理的数据大小
split_count = 2
# 需要的线程个数
times = math.ceil(len(_l) / split_count)
count = 0
for item in range(times):
_list = _l[count: count + split_count]
# 线程相关处理
thread = Thread(target=work, args=(item, _list,))
thread_list.append(thread)
# 在子线程中运行任务
thread.start()
count += split_count # 线程同步,等待子线程结束任务,主线程再结束
for _item in thread_list:
_item.join() def work(df, _list):
"""
每个线程执行的任务,让程序随机sleep几秒
:param df:
:param _list:
:return:
"""
sleep_time = random.randint(1, 5)
print(f'count is {df},sleep {sleep_time},list is {_list}')
time.sleep(sleep_time)
_result_list.append(df) if __name__ == '__main__':
split_df()
print(len(_result_list), _result_list)
测试结果:

方法二:使用ThreadPoolExecutor.map
代码:
# -*- coding: utf-8 -*-
import math
import random
import time
from concurrent.futures import ThreadPoolExecutor def split_list():
# 线程列表
new_list = []
count_list = []
# 需要处理的数据
_l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 每个线程处理的数据大小
split_count = 2
# 需要的线程个数
times = math.ceil(len(_l) / split_count)
count = 0
for item in range(times):
_list = _l[count: count + split_count]
new_list.append(_list)
count_list.append(count)
count += split_count
return new_list, count_list def work(df, _list):
""" 线程执行的任务,让程序随机sleep几秒
:param df:
:param _list:
:return:
"""
sleep_time = random.randint(1, 5)
print(f'count is {df},sleep {sleep_time},list is {_list}')
time.sleep(sleep_time)
return sleep_time, df, _list def use():
new_list, count_list = split_list()
with ThreadPoolExecutor(max_workers=len(count_list)) as t:
results = t.map(work, new_list, count_list) # 或执行如下两行代码
# pool = ThreadPoolExecutor(max_workers=5)
# 使用map的优点是 每次调用回调函数的结果不用手动的放入结果list中
# results = pool.map(work, new_list, count_list) # map返回一个迭代器,其中的回调函数的参数 最好是可以迭代的数据类型,如list;如果有 多个参数 则 多个参数的 数据长度相同;
# 如: pool.map(work,[[1,2],[3,4]],[0,1]]) 中 [1,2]对应0 ;[3,4]对应1 ;其实内部执行的函数为 work([1,2],0) ; work([3,4],1)
# map返回的结果 是 有序结果;是根据迭代函数执行顺序返回的结果
print(type(results))
# 如下2行 会等待线程任务执行结束后 再执行其他代码
for ret in results:
print(ret)
print('thread execute end!') if __name__ == '__main__':
use()
测试结果:

参考链接:https://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_1103_3days.html
python多线程之threading、ThreadPoolExecutor.map的更多相关文章
- python多线程之Threading
什么是线程? 线程是操作系统内核调度的基本单位,一个进程中包含一个或多个线程,同一个进程内的多个线程资源共享,线程相比进程是“轻”量级的任务,内核进行调度时效率更高. 多线程有什么优势? 多线程可以实 ...
- “死锁” 与 python多线程之threading模块下的锁机制
一:死锁 在死锁之前需要先了解的概念是“可抢占资源”与“不可抢占资源”[此处的资源可以是硬件设备也可以是一组信息],因为死锁是与不可抢占资源有关的. 可抢占资源:可以从拥有他的进程中抢占而不会发生副作 ...
- python多线程之threading模块
threading模块中的对象 其中除了Thread对象以外,还有许多跟同步相关的对象 threading模块支持守护线程的机制 Thread对象 直接调用法 import threading imp ...
- python 线程之 threading(四)
python 线程之 threading(三) http://www.cnblogs.com/someoneHan/p/6213100.html中对Event做了简单的介绍. 但是如果线程打算一遍一遍 ...
- python 线程之 threading(三)
python 线程之 threading(一)http://www.cnblogs.com/someoneHan/p/6204640.html python 线程之 threading(二)http: ...
- python并发编程之threading线程(一)
进程是系统进行资源分配最小单元,线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.进程在执行过程中拥有独立的内存单元,而多个线程共享内存等资源. 系列文章 py ...
- python利用(threading,ThreadPoolExecutor.map,ThreadPoolExecutor.submit) 三种多线程方式处理 list数据
需求:在从银行数据库中取出 几十万数据时,需要对 每行数据进行相关操作,通过pandas的dataframe发现数据处理过慢,于是 对数据进行 分段后 通过 线程进行处理: 如下给出 测试版代码,通过 ...
- python多线程之Condition(条件变量)
#!/usr/bin/env python # -*- coding: utf-8 -*- from threading import Thread, Condition import time it ...
- python多线程之semaphore(信号量)
#!/usr/bin/env python # -*- coding: utf-8 -*- import threading import time import random semaphore = ...
随机推荐
- Python对字典分别按键(key)和值(value)进行排序
使用sorted函数进行排序 sorted(iterable,key,reverse),sorted一共有iterable,key,reverse这三个参数;其中iterable表示可以迭代的对象,例 ...
- 数据库-MongoDb
*本文总结下使用Mongodb遇到的问题: 1. 安装完MongoDb后先启动服务端,然后再启动客户端: 直接上图: 注意点:mongod.exe :是用来连接到mongo数据库服务器的,即服务器端. ...
- 新建一个浏览器APP
安卓开发环境准备好了,试试新建一个浏览器程序吧 1.Start a new Android Studio Project 2.选这个像微信一样的样式 3.选择语言和版本 4.等待创建完成,拖一个Web ...
- Git - p4merge
Windows 下配置 先确保 p4merge 的路径(默认:C:\Program Files\Perforce\)在环境变量中 C:\Users\zjffu>where p4merge C:\ ...
- Fragment 的 replace 和 add 方法的区别?
Fragment 本身并没有 replace 和 add 方法,这里的理解应该为使用 FragmentManager 的 replace 和 add 两种方法切换 Fragment 时有什么不同.我们 ...
- 有关于Git操作(持续更新)
Git分支: 查看分支:git branch 创建分支:git branch <name> 切换分支:git checkout <name> 创建+切换分支:git check ...
- 使用多个fixture和fixture直接互相调用
使用多个fixture 如果用例需要用到多个fixture的返回数据,fixture也可以return一个元组.list或字典,然后从里面取出对应数据. # test_fixture4.py impo ...
- java:LeakFilling(Spring)
1.配置文件总结: bean节点: id:用户自定义名称,用于标识当前对象,可以通过getBean(String id)从容器中获取该对象. class:要交给spring容器创建的对象的全类名(包名 ...
- Series的idxmax和argmax
转载至:https://www.cnblogs.com/liulangmao/p/9211537.html pandas Series 的 argmax 方法和 idxmax 方法用于获取 Serie ...
- Python密码登录程序的思考--学与习
# 初学者的起步,对于开始的流程图结构还不太熟悉 # 思考: 1,write()与writelines()的区别,前者确定为字符串,后者为序列(列表,字典.元组等),自动为你迭代输入# ...