我的CPU数是8。这意味着理论上我可以有16个线程来运行我的多线程程序。我有几个问题。
答案 0 :(得分:5)
我的CPU数是8。
您可能要检查它们是否为logical CPUs or physical CPUs。
这意味着从理论上讲我可以有16个线程来运行我的多线程程序。
不,您可以根据需要设置尽可能多的线程(在一定范围内;如果您创建了数千个线程,则执行起来可能会不太顺利)。操作系统将根据需要将它们调度到物理(或逻辑)CPU上。
如果我创建20个线程并同时启动它们会发生什么?既然由于硬件限制我不能拥有那么多线程,操作系统是应该处理它还是必须从我这边处理它?</ p>
操作系统处理它。但是,操作系统必须决定哪个线程将以什么顺序运行,并且您可能不同意操作系统所做的选择,因此创建太多线程可能会适得其反。另外,线程之间的切换会带来固有的开销,因此,如果您的工作受CPU限制,那么通常不希望创建的线程多于逻辑CPU。
即使理论上有16个线程,某些线程也可能已被其他程序利用。有没有办法在Python中获得“可利用的线程数”并动态地利用最大可能的线程数?
我们在这里遇到了问题:Python有一个global interpreter lock,所以唯一正确的答案是“我可以有用地创建多少个线程?” (与“ Python和操作系统允许我创建多少个线程?”相对)为 。如果创建多个线程,则一次只能有一个线程可以执行Python字节码。其他人将不得不等待锁,并且将无法做任何有用的事情。
Python线程的目的不是在多个CPU上工作。而是将它们用于多路复用I / O。也就是说,您可以在任意数量的线程上启动I / O操作(例如读取或写入文件,网络套接字,管道或其他IPC机制),并且所有这些I / O操作将并行运行。当执行I / O操作时,Python会释放GIL,因此它不会阻止这种并行性。如果您要编写某种服务器,这将很有用。在此用例中,您可以为每个I / O操作创建一个线程(如果不需要太多),或者创建一个线程池,该池动态地将工作项分配给工作线程,例如使用concurrent.futures.ThreadPoolExecutor
。
答案 1 :(得分:1)
您正在混合使用硬件方面的超线程和软件方面的线程。第一个基本上模拟了比您更多的CPU内核。但这与我们在软件编程中所谓的线程无关。
线程(软件的)与计算机拥有的资源不同,可以分配给进程。线程就像进程,但是它们共享其父进程的地址空间。因此他们可以访问相同的变量-不同的进程通常无法做到这一点。
因此,您可以打开一个文本编辑器20次,因此您也可以打开一个新线程20次。不过,因为您可以做并不意味着您应该:https://stackoverflow.com/a/481979/8575607
进一步阅读:Maximum number of threads per process in Linux?
编辑:添加到kevin的答案:仍然有使用多个线程的原因(例如,如果您同时访问软件并绘制UI),那么GIL并没有从中受益。或例如呈现非阻塞的UI叠加层。尽管一个cpython进程中没有两个原子指令同时执行,但线程仍以并行方式执行。 (这不是一句话,因为我还没有足够的声誉可以在其他人的帖子下发表评论)