python-3.x - 有没有办法使用python将不同的作业(进程)分配给linux中的特定核心?

标签 python-3.x linux multiprocessing

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

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

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 的组合。文档字符串说:

Signature: os.sched_setaffinity(pid, mask, /)

Docstring:

Set the CPU affinity of the process identified by pid to mask.

mask should be an iterable of integers identifying CPUs.

Type: builtin_function_or_method

我找不到特定于 Python 的文档,但是 these man pages应该是很好的第一个信息来源。

更新:

我决定研究 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) 的所有进程的亲和性,但这只是因为我发现使用 cycle 就像我对 map_hack 所做的一样。我还想证明您可以为任何(合法)数量的 CPU 设置关联。

我建议您通读代码并确保通过阅读相关文档并通过更改一些参数来玩弄它来理解它。不用说,所有的 print 语句只是为了让我们自己相信这些方法有效。

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

window :

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

These functions control how a process is allocated CPU time by the operating system. They are only available on some Unix platforms. For more detailed information, consult your Unix manpages.

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

关于python-3.x - 有没有办法使用python将不同的作业(进程)分配给linux中的特定核心?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58398996/

相关文章:

python - 使用 pyinstaller 和 scipy 模块将 py 文件转换为 exe 文件时出错。知道可能是什么问题吗?

python-3.x - TensorFlow 中的 Hello World

Python multiprocessing.Pool 不会立即启动

Python - 循环遍历 csv 文件行值

django - 如何在 Django Oscar 中执行库存更新过程

linux - 在 Windows 上运行以下 linux 命令

linux - 如何在 linux 上通过命令行发送嵌入在邮件中的 png 文件?

Linux CLI 查找没有子路径的 dir 路径 - 结果只有父路径

python - 如何并行循环以更改 Python 字典中的对象?

python - 为什么 multiprocessing.pool.map 引发 PicklingError(编码)?