我正在尝试使用python将一些数字(100)数据集插入SQL服务器。我正在使用多线程在循环中创建100个线程。所有这些都是在同一时间开始,这使数据库陷入困境。我想将我的线程分组为5组,一旦完成该组,我想开始下一组线程,依此类推。由于我是python和多线程的新手,任何帮助都将受到高度赞赏。请在下面找到我的代码。
for row in datasets:
argument1=row[0]
argument2=row[1]
jobs=[]
t = Thread(target=insertDataIntoSQLServer, args=(argument1,argument2,))
jobs.append(t)
t.start()
for t in jobs:
t.join()
答案 0 :(得分:1)
您可以创建ThreadPoolExecutor
并指定max_workers=5
。
请参阅here。
您可以使用 functools.partial
将您的函数转换为所需的0参数函数。
编辑:当您submit
到执行程序时,可以使用函数名传递args。谢谢,罗兰史密斯,提醒我partial
是一个坏主意。有更好的方法。
答案 1 :(得分:1)
在Python 2和3上,您可以使用multiprocessing.ThreadPool
。这就像multiprocessing.Pool
,但使用线程而不是进程。
import multiprocessing
datasets = [(1,2,3), (4,5,6)] # Iterable of datasets.
def insertfn(data):
pass # shove data to SQL server
pool = multiprocessing.ThreadPool()
p.map(insertfn, datasets)
默认情况下,Pool
将创建与CPU具有核心一样多的工作线程。使用更多线程可能没有帮助,因为它们将争夺CPU时间。
请注意,我已将数据分组为元组。这是解决池工作者的一个参数限制的一种方法。
在Python 3上,您还可以使用ThreadPoolExecutor
。
但是请注意,在具有全局解释器锁的Python实现(如"标准" CPython)上,一次只有一个线程可以执行Python字节码。因此,使用大量线程不会自动提高性能。线程可能有助于I / O绑定的操作。如果一个线程正在等待I / O,则另一个线程可以运行。
答案 2 :(得分:1)
首先请注意,您的代码无法按预期运行:它通过循环将jobs
设置为每个时间的空列表,因此在循环结束后您只需join()
1}}最后创建的线程。
通过将jobs=[]
移出循环来修复它。之后,您可以在t.start()
:
if len(jobs) == 5:
for t in jobs:
t.join()
jobs = []
我个人会使用某种池(正如其他答案所示),但很容易直接得到你的想法。