Python 将具有无限线程的多线程代码转换为具有最大同时运行线程数的多线程代码
我有一个脚本,它通过多线程执行某个函数。现在,有趣的是,只有与CPU核一样多的线程并行运行。 现在,当前代码(1:)使用threading.thread语句创建1000个线程,并同时运行它们。 我想将其转换为同时只运行固定数量的线程(例如8个),并将其余线程放入队列中,直到执行线程/cpu核心可以自由使用为止 1:Python 将具有无限线程的多线程代码转换为具有最大同时运行线程数的多线程代码,python,multithreading,python-multithreading,threadpoolexecutor,Python,Multithreading,Python Multithreading,Threadpoolexecutor,我有一个脚本,它通过多线程执行某个函数。现在,有趣的是,只有与CPU核一样多的线程并行运行。 现在,当前代码(1:)使用threading.thread语句创建1000个线程,并同时运行它们。 我想将其转换为同时只运行固定数量的线程(例如8个),并将其余线程放入队列中,直到执行线程/cpu核心可以自由使用为止 1: import threading nSim = 1000 def simulation(i): print(str(threading.current_thread().
import threading
nSim = 1000
def simulation(i):
print(str(threading.current_thread().getName()) + ': '+ str(i))
if __name__ == '__main__':
threads = [threading.Thread(target=simulation,args=(i,)) for i in range(nSim)]
for t in threads:
t.start()
for t in threads:
t.join()
Q1:代码2:是否按照我的描述执行?(同时运行最多线程数的多线程)是否正确?(我想是的,但我不是100%确定)
Q2:现在代码同时启动1000个线程,并在8个线程上执行它们。有没有一种方法可以只在执行线程/cpu内核可以自由使用时启动一个新线程(这样我就不会有990个线程调用在可能的情况下从一开始就等待执行)
Q3:有没有办法跟踪哪个cpu内核执行了哪个线程?只是为了证明代码正在做它应该做的事情
2:
import threading
import multiprocessing
print(multiprocessing.cpu_count())
from concurrent.futures import ThreadPoolExecutor
nSim = 1000
def simulation(i):
print(str(threading.current_thread().getName()) + ': '+ str(i))
if __name__ == '__main__':
with ThreadPoolExecutor(max_workers=8) as executor:
for i in range (nSim):
res = executor.submit(simulation, i)
print(res.result())
A1:为了限制可以同时访问某些资源的线程数量,您可以使用线程。实际上,信号量1000个线程不会给您带来巨大的速度提升,建议每个进程的线程数量为mp.cpu\u count()*1或mp.cpu\u count()*2在一些文章中。还要注意,线程在python中适用于IO操作,但由于GIL的原因,线程不适用于计算 A2.如果您只想同时运行其中的8个线程,为什么需要这么多线程?只创建8个线程,然后在任务准备就绪时为它们提供任务,为此您需要使用queue.queue()这是线程安全的。但是在您的具体示例中,您可以使用whileinsidesimulation函数对每个线程执行250次测试,顺便说一句,在这种情况下您不需要信号量 当我们谈论多线程时,一个进程有多个线程
A1:为了限制可以同时访问某些资源的线程数量,可以使用线程。实际上,信号量1000个线程不会给您带来巨大的速度提升,建议每个进程的线程数量为mp.cpu\u count()*1或mp.cpu\u count()*2在一些文章中。还要注意,线程在python中适用于IO操作,但由于GIL的原因,线程不适用于计算 A2.如果您只想同时运行其中的8个线程,为什么需要这么多线程?只创建8个线程,然后在任务准备就绪时为它们提供任务,为此您需要使用queue.queue()这是线程安全的。但是在您的具体示例中,您可以使用whileinsidesimulation函数对每个线程执行250次测试,顺便说一句,在这种情况下您不需要信号量 当我们谈论多线程时,一个进程有多个线程
A1:不,您的代码提交一个任务,在
res
中接收一个Future
,然后调用result
,它等待结果。只有在前一个任务完成后,才会将新任务分配给线程。只有一个工作线程真正工作一次又一次地打电话
查看ThreadPool.map
(实际上是Pool.map
),而不是submit
,以便在工作人员之间分配任务
A2:这里最多只使用8个线程(工作线程的数量)。如果使用map
可以存储1000个任务的输入数据(需要内存),但不会创建额外的线程
A3:据我所知不是这样。线程没有绑定到核心,它可能会在它们之间快速切换。A1:不,您的代码提交一个任务,在
res
中接收一个Future
,然后调用result
,该等待结果。只有在前一个任务完成后,一个新任务才会被赋予线程。只有一个worker线程一次都在工作
查看ThreadPool.map
(实际上是Pool.map
),而不是submit
,以便在工作人员之间分配任务
A2:这里最多只使用8个线程(工作线程的数量)。如果使用map
可以存储1000个任务的输入数据(需要内存),但不会创建额外的线程
A3:据我所知不是这样。线程没有绑定到核心,它可能会在它们之间快速切换。A1:谢谢,我没有意识到一个工作线程正在等待另一个工作线程执行任务。pool.map的问题是我不知道如何设置参数“I”(这对于“提交”函数A2来说很简单:是的,它使用内存这一事实并不一定是个问题,但如果任务只能在操作系统A3执行时使用内存,则效率会更高:我之所以问这个问题,是因为我正在使用python dymola接口从python运行1000次模拟。最快的方法是o这是当每个cpu内核上只运行一个模拟时;性能方面A1:谢谢,我没有意识到一个工人正在等待另一个工人执行任务。pool.map的问题是我不知道如何设置参数“I”(这对于“提交”函数A2来说很简单:是的,它使用内存这一事实并不一定是个问题,但如果任务只能在操作系统A3执行时使用内存,则效率会更高:我之所以问这个问题,是因为我正在使用python dymola接口从python运行1000次模拟。最快的方法是o这是指每个cpu内核上只运行一个模拟;性能方面A2:问题是
import threading
import time
import multiprocessing as mp
def simulation(i, _s):
# s is threading.Semaphore()
with _s:
print(str(threading.current_thread().getName()) + ': ' + str(i))
time.sleep(3)
if name == 'main':
print("Cores number: {}".format(mp.cpu_count()))
# recommended number of threading is mp.cpu_count()*1 or mp.cpu_count()*2 in some articles
nSim = 25
s = threading.Semaphore(4) # max number of threads which can work simultaneously with resource is 4
threads = [threading.Thread(target=simulation, args=(i, s, )) for i in range(nSim)]
for t in threads:
t.start()
# just to prove that all threads are active in the start and then their number decreases when the work is done
for i in range(6):
print("Active threads number {}".format(threading.active_count()))
time.sleep(3)