<p><strong>注意</strong>:此方法在windows上不起作用,仅在linux上测试。</p>
<p><strong>使用<code>multiprocessing.Process</code></strong>:</p>
<p>在使用<code>Process()</code>时,为每个进程分配物理核心非常容易。您可以创建一个for循环,循环遍历每个核心,并使用<code>taskset -p [mask] [pid]</code>将新进程分配给新核心:</p>
<pre><code>import multiprocessing
import os
def foo():
return
if __name__ == "__main__" :
for process_idx in range(multiprocessing.cpu_count()):
p = multiprocessing.Process(target=foo)
os.system("taskset -p -c %d %d" % (process_idx % multiprocessing.cpu_count(), os.getpid()))
p.start()
</code></pre>
<p>我的工作站上有32个内核,因此我将在此处显示部分结果:</p>
<pre><code>pid 520811's current affinity list: 0-31
pid 520811's new affinity list: 0
pid 520811's current affinity list: 0
pid 520811's new affinity list: 1
pid 520811's current affinity list: 1
pid 520811's new affinity list: 2
pid 520811's current affinity list: 2
pid 520811's new affinity list: 3
pid 520811's current affinity list: 3
pid 520811's new affinity list: 4
pid 520811's current affinity list: 4
pid 520811's new affinity list: 5
...
</code></pre>
<p>如您所见,这里每个进程的前一个和新的关联。第一个进程用于所有核心(0-31),然后分配给核心0,第二个进程默认分配给核心0,然后将其关联性更改为下一个核心(1),依此类推。</p>
<p><strong>使用<code>multiprocessing.Pool</code></strong>:</p>
<p><strong>警告</strong>:此方法需要调整<code>pool.py</code>模块,因为据我所知,您无法从<code>Pool()</code>中提取pid。此外,在<code>python 2.7</code>和<code>multiprocessing.__version__ = '0.70a1'</code>上也测试了这种变化。</p>
<p>在<code>Pool.py</code>中,找到调用<code>_task_handler_start()</code>方法的行。在下一行中,您可以使用(我将<code>import os</code>放在这里,这样读者就不会忘记导入它)将池中的进程分配给每个“物理”核心:</p>
<pre><code>import os
for worker in range(len(self._pool)):
p = self._pool[worker]
os.system("taskset -p -c %d %d" % (worker % cpu_count(), p.pid))
</code></pre>
<p>你完了。测试:</p>
<pre><code>import multiprocessing
def foo(i):
return
if __name__ == "__main__" :
pool = multiprocessing.Pool(multiprocessing.cpu_count())
pool.map(foo,'iterable here')
</code></pre>
<p>结果:</p>
<pre><code>pid 524730's current affinity list: 0-31
pid 524730's new affinity list: 0
pid 524731's current affinity list: 0-31
pid 524731's new affinity list: 1
pid 524732's current affinity list: 0-31
pid 524732's new affinity list: 2
pid 524733's current affinity list: 0-31
pid 524733's new affinity list: 3
pid 524734's current affinity list: 0-31
pid 524734's new affinity list: 4
pid 524735's current affinity list: 0-31
pid 524735's new affinity list: 5
...
</code></pre>
<p>请注意,对<code>pool.py</code>的此修改将作业自动分配给核心轮。因此,如果分配的作业比cpu核心多,那么最终会在同一个核心上有多个作业。</p>
<p><strong>编辑:</strong></p>
<p>OP正在寻找的是一个能够在特定核心上启动池的<code>pool()</code>。为此,需要对<code>multiprocessing</code>进行更多的调整(首先撤消上述更改)。</p>
<p><strong>警告:</strong></p>
<p>不要试图复制粘贴函数定义和函数调用。只复制粘贴应该在<code>self._worker_handler.start()</code>之后添加的部分(如下所示)。注意,我的<code>multiprocessing.__version__</code>告诉我版本是<code>'0.70a1'</code>,但是只要您添加需要添加的内容就无所谓了:</p>
<p><strong><code>multiprocessing</code>的<code>pool.py</code>:</strong></p>
<p>将<code>cores_idx = None</code>参数添加到<code>__init__()</code>定义中。在我的版本中,在添加后如下所示:</p>
<pre><code>def __init__(self, processes=None, initializer=None, initargs=(),
maxtasksperchild=None,cores_idx=None)
</code></pre>
<p>此外,还应在<code>self._worker_handler.start()</code>之后添加以下代码:</p>
<pre><code>if not cores_idx is None:
import os
for worker in range(len(self._pool)):
p = self._pool[worker]
os.system("taskset -p -c %d %d" % (cores_idx[worker % (len(cores_idx))], p.pid))
</code></pre>
<p><strong><code>multiprocessing</code>的<code>__init__.py</code></strong>:</p>
<p>将一个<code>cores_idx=None</code>参数添加到中<code>Pool()</code>的定义以及返回部分中的另一个<code>Pool()</code>函数调用。在我的版本中,它看起来像:</p>
<pre><code>def Pool(processes=None, initializer=None, initargs=(), maxtasksperchild=None,cores_idx=None):
'''
Returns a process pool object
'''
from multiprocessing.pool import Pool
return Pool(processes, initializer, initargs, maxtasksperchild,cores_idx)
</code></pre>
<p>你完了。以下示例仅在核心0和2上运行5个工作线程池:</p>
<pre><code>import multiprocessing
def foo(i):
return
if __name__ == "__main__":
pool = multiprocessing.Pool(processes=5,cores_idx=[0,2])
pool.map(foo,'iterable here')
</code></pre>
<p>结果:</p>
<pre><code>pid 705235's current affinity list: 0-31
pid 705235's new affinity list: 0
pid 705236's current affinity list: 0-31
pid 705236's new affinity list: 2
pid 705237's current affinity list: 0-31
pid 705237's new affinity list: 0
pid 705238's current affinity list: 0-31
pid 705238's new affinity list: 2
pid 705239's current affinity list: 0-31
pid 705239's new affinity list: 0
</code></pre>
<p>当然,通过删除<code>cores_idx</code>参数,您仍然可以使用<code>multiprocessing.Poll()</code>的常规功能。</p>