有没有一种方法可以使用python将不同的作业(进程)分配给linux中的特定核心



我有python函数,它们应该在使用多核的linux环境中并行运行。有没有办法明确指定每个流程应该使用哪个核心?

目前,我正在使用python多处理模块在4个核心中作为并行进程运行这些python函数。

import multiprocessing as mp
def hello(name, msg):
try:
print("Hello {}".format(name))
print(msg)
return true
except Exception:
return False
pool = mp.Pool(mp.cpu_count())
msg = "It's a holiday!"
name_list = ["A", "B", "C"]
hello_status = pool.starmap(hello,[(name, msg) for name in name_list])
print(hello_status)

可能是os.sched_setaffinityos.sched_getaffinity的组合。文档字符串显示:

签名:os.sched_setaffinity(pid,mask,/)

文档字符串:

将pid标识的进程的CPU相关性设置为掩码。

掩码应该是标识CPU的整数的可迭代。

类型:内置函数或方法

我找不到Python特定的文档,但这些手册页应该是很好的第一个信息来源。

更新:

我决定研究multiprocessing模块,并编写一个工作示例。我用multiprocessing.Pool类想出了两种方法。第一种方法是将initializer参数传递给Pool构造函数调用。第二种是使用Pool.map函数。

import os
from itertools import cycle
import multiprocessing as mp
def _myinit():
my_pid = os.getpid()
old_aff = os.sched_getaffinity(0)
os.sched_setaffinity(0, [0, 3])
new_aff = os.sched_getaffinity(0)
print("My pid is {} and my old aff was {}, my new aff is {}".format(my_pid, old_aff, new_aff))

def map_hack(AFF):
my_pid = os.getpid()
old_aff = os.sched_getaffinity(0)
os.sched_setaffinity(0, AFF)
return (my_pid, old_aff, os.sched_getaffinity(0))
PROCESSES = os.cpu_count()
# just an example iterable you could use for the map_hack
# elements of cpus must be iterables, because of os.sched_setaffinity
_mycpus = cycle(os.sched_getaffinity(0))
cpus = [[next(_mycpus)] for x in range(PROCESSES)]
# Since Python 3.3 context managers are supported for mp.Pool
# using initializer argument to change affinity
with mp.Pool(processes=PROCESSES, initializer=_myinit) as pool:
# do something conditional on your affinity 
pool.close()
pool.join()
print("")
# using mp.Pool.map hack to change affinity
with mp.Pool(processes=PROCESSES) as pool:
for x in pool.map(map_hack, cpus, chunksize=1):
print("My pid is {} and my old aff was {}, my new aff is {}".format(*x))
# do something conditional on your affinity 
pool.close()
pool.join()

注意,使用initializer,我对第一个和第四个CPU(0,3)的所有进程的亲和性进行了硬编码,但这只是因为我发现像使用map_hack那样使用cycle有点困难。我还想证明,您可以为任何(合法)数量的cpu设置亲和性。

我建议你仔细阅读代码,并确保通过阅读相关文档和更改一些参数来理解它。不用说,所有的print声明都只是为了让我们相信这些方法是有效的。

最后,如果您想要更多的控制,我建议您使用mp.Process对象,而不是mp.Poolos中的相同工具也应该派上用场。

WINDOWS:

如果您使用的是Windows,这将不起作用。来自文档:

这些函数控制操作系统如何分配进程的CPU时间。它们仅在某些Unix平台上可用。有关更多详细信息,请参阅Unix手册页。

在这种情况下,您可以查看win32process,特别是win32process.SetProcessAffinityMaskwin32process.GetProcessAffinityMask,请参阅此处。

相关内容

  • 没有找到相关文章