您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

我的Python进程在哪些CPU内核上运行?

我的Python进程在哪些CPU内核上运行?

Python解释器一次只使用一个cpu内核来运行所有线程,这是真的吗?

不可以。GIL和cpu关联性是不相关的概念。无论如何,在阻止I / O操作,在C扩展内部进行长时间的cpu密集型计算时,都可以释放GIL。

如果线程在GIL上被阻塞;它可能不在任何cpu内核上,因此可以说,纯Python多线程代码cpython实现中一次只能使用一个cpu内核。

换句话说,Python解释器会话1(从图中)是否将在一个cpu内核上运行所有3个线程(Main_thread,TCP_thread和UDP_thread)?

我认为cpython不会隐式管理cpu亲和力。可能依赖于OS调度程序来选择在哪里运行线程。Python线程是在真实OS线程之上实现的。

还是Python解释器能够将它们分布在多个内核上?

要找出可用的cpu数量

>>> import os
>>> len(os.sched_getaffinity(0))
16

同样,是否在不同的cpu上调度线程并不取决于Python解释器。

假设问题1的答案是“多核”,我是否可以通过一些零星的打印语句跟踪每个线程在哪个核上运行?如果对问题1的回答是“仅一个核心”,我是否有办法跟踪它是哪个?

我想,一个特定的cpu可能会从一个时隙更改为另一个时隙。您可以看一下类似/proc/<pid>/task/<tid>/status旧Linux内核上的内容。在我的机器上,task_cpu可以从/proc/<pid>/stat或读取/proc/<pid>/task/<tid>/stat

>>> open("/proc/{pid}/stat".format(pid=os.getpid()), 'rb').read().split()[-14]
'4'

对于当前的便携式解决方案,请参阅是否psutil公开此类信息。

您可以将当前进程限制为一组cpu

os.sched_setaffinity(0, {0}) # current process on 0-th core

对于这个问题,我们忘记了线程,但是我们专注于Python中的子进程机制。启动一个新的子进程意味着启动一个新的Python解释器会话/ shell。这个对吗?

是。subprocess模块创建新的OS进程。如果您运行python可执行文件,则它将启动一个新的Python交互器。如果运行bash脚本,则不会创建新的Python解释器,即,运行bash可执行文件不会启动新的Python解释器/会话/等。

假设它是正确的,Python是否足够聪明,可以使单独的解释器会话在另一个cpu内核上运行?有没有一种方法可以跟踪此消息,也许还有一些零星的打印语句?

参见上文(即OS决定在哪里运行线程,并且可能有OS API公开线程在何处运行)。

multiprocessing.Process(target=foo, args=(q,)).start()

multiprocessing.Process 还创建一个新的OS进程(运行一个新的Python解释器)。

实际上,我的子进程是另一个文件。所以这个例子对我不起作用。

Python使用模块来组织代码。如果您的代码在其中,another_file.pyimport another_file在您的主模块中并传递another_file.foomultiprocessing.Process

但是,如何将其与p = subprocess.Popen(..)进行比较?如果我使用subprocess.Popen(..)相对于multiprocessing.Process(..)来启动新进程(或者应该说“ Python解释器实例”),是否有关系?

multiprocessing.Process()可能在之上实现subprocess.Popen()multiprocessing提供类似于threadingAPI的API,并且抽象化了python进程之间的通信细节(如何序列化Python对象以在进程之间发送)。

如果没有cpu密集型任务,则可以在单个进程中运行GUI和I / O线程。如果你有一个系列的cpu密集型任务,然后同时利用多个cpu,或者使用多线程使用C扩展,例如lxmlregexnumpy(或者你自己的一个使用创建的用Cython,可以在长时间的计算释放GIL)或卸载它们变成独立的进程(一种简单的方法是使用)提供的进程池concurrent.futures

社区讨论提出了一个新问题。产生新进程时(在新的Python解释器实例中)显然有两种方法

# Approach 1(a)
p = subprocess.Popen(['python', mySubprocessPath], shell = True)

# Approach 1(b) (J.F. Sebastian)
p = subprocess.Popen([sys.executable, mySubprocessPath])

# Approach 2
p = multiprocessing.Process(target=foo, args=(q,))

__在POSIX上, 方法1(a)”错误的(尽管在Windows上可以使用)。为了实现可移植性,除非您知道您需要使用方法1(b)”cmd.exe在这种情况下,请传递一个字符串,以确保使用了正确的命令行转义符)。

第二种方法一个明显的缺点,那就是它只针对一个函数-而我需要打开一个新的Python脚本。无论如何,两种方法在实现目标上是否相似?

subprocess创建新进程, 任何 进程,例如,您都可以运行bash脚本。multprocessing用于在另一个进程中运行Python代码导入 python模块并运行其功能比将其作为脚本运行更灵活。

python 2022/1/1 18:35:29 有389人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶