Windows 上的 os.exec
Posted
技术标签:
【中文标题】Windows 上的 os.exec【英文标题】:os.exec on Windows 【发布时间】:2011-10-23 16:45:12 【问题描述】:我有一个将os.execvp
调用到另一个Python 实例的脚本。执行此操作后,我似乎附加到了一个 cmd.exe
实例,而不是我刚刚创建的 Python 实例。然而,Python 实例会响应 Ctrl+C。
H:\bin>Python 3.2.1 (default, Jul 10 2011, 21:51:15) [MSC v.1500
32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print('hi')
Can't find file ('hi')
H:\bin>
H:\bin>
KeyboardInterrupt
>>> echo hi
hi
拨打exec
:
from sys import argv
os.execvp('python', argv)
根据在 Linux 上可能看到的行为,如何将原始 Python 实例替换为新实例?
【问题讨论】:
相关:bugs.python.org/issue9148。根据 Amaury Forgeot d'Arc 的 comment - 在 Windows 上,exec()
并没有真正取代当前进程。它创建一个新进程(使用新的 pid),并退出当前进程。因此调用程序只看到脚本已经终止。我在 Windows 上没有看到任何简单的解决方案,除了使用 subprocess.Popen()
,并在子进程终止时退出脚本。在你的情况下,它看起来像一个可能的解决方案吗?
感谢@PiotrDobrogost 的有用评论。如果您将 Python 问题中的材料与此问题相关联,则将构成解决方案。
你的意思是先调用subprocess.Popen()
然后退出原来的Python进程?
@PiotrDobrogost:是的,为了关注同样问题的人们的利益,他们应该得到一个干净的解决方案和理由。
@MattJoiner 嗨,我在尝试将库移植到 Windows 时偶然发现了这一点。我正在努力寻找一个基于subprocess.Popen
的完整的工作示例。知道在哪里可以找到吗?
【参考方案1】:
在 Unix 上,执行二进制文件分为两个阶段 - fork(3) 克隆当前进程,exec(3) 将可执行文件加载到地址空间。在 Windows 上只有 CreateProcess 与 fork+exec 做同样的事情。
为了便携性,最好的办法是使用subprocess.Popen(与 os.* 对应物不同,它在 Windows 上也可以正确引用文件名),如 http://docs.python.org/library/subprocess.html#replacing-the-os-spawn-family
【讨论】:
您能否链接到提及 Windows 上不同的os.exec*
行为?我的印象是 exec 在 Windows 上受支持,请参阅here
您发布的 url 中的第一段:“这个系列中的每个函数都加载并执行一个 new 进程”。在 MS CRT 中,它们只是 CreateProcess 的包装器。
当一个_exec函数调用成功时,新进程被放置在调用进程之前占用的内存中。必须有足够的内存来加载和执行新进程。 在示例 exec 调用之后,还有一条注释 /* This point is reached only if exec fails. */
。
我怀疑该行是从 POSIX.1 规范中逐字复制的。 “达到这一点”:参见任何 _exec 的描述,“返回值”子句。 “如果成功,这些函数不会返回到调用进程”,它们会在成功的 CreateProcess() 调用 iirc 时调用 ExitProcess()。
有关 CreateProcess 如何在内部工作的详细信息,请参阅scribd.com/doc/51979000/122/Flow-of-CreateProcess以上是关于Windows 上的 os.exec的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Windows 10 上的容器连接到 docker 主机(Docker for Windows)
Windows 上的 WaitOnAddress() 在 Linux 上的完全等价物是啥?