进程管理
下列函数可用于创建和管理进程。
所有 exec*
函数都接受一个参数列表,用来给新程序加载到它的进程中。在所有情况下,传递给新程序的第一个参数是程序本身的名称,而不是用户在命令行上输入的参数。对于 C 程序员来说,这就是传递给 main()
函数的 argv[0]
。例如,os.execv('binecho', ['foo', 'bar'])
只会在标准输出上打印 bar
,而 foo
会被忽略。
- os.abort()
- 发送
SIGABRT
信号到当前进程。在 Unix 上,默认行为是生成一个核心转储。在 Windows 上,该进程立即返回退出代码3
。请注意,使用signal.signal()
可以为SIGABRT
注册 Python 信号处理程序,而调用本函数将不会调用按前述方法注册的程序。
- os.add_dll_directory(path)
- 将路径添加到 DLL 搜索路径。
当需要解析扩展模块的依赖时(扩展模块本身通过 sys.path
解析),会使用该搜索路径,ctypes
也会使用该搜索路径。
要移除目录,可以在返回的对象上调用 close(),也可以在 with
语句内使用本方法。
参阅 Microsoft 文档 [https://msdn.microsoft.com/44228cf2-6306-466c-8f16-f513cd3ba8b5] 获取如何加载 DLL 的信息。
引发一个 审计事件 os.add_dll_directory
并附带参数 path
。
Availability: Windows.
Added in version 3.8: 早期版本的 CPython 解析 DLL 时用的是当前进程的默认行为。这会导致不一致,比如不是每次都会去搜索 PATH
和当前工作目录,且系统函数(如 AddDllDirectory
)失效。
在 3.8 中,DLL 的两种主要加载方式现在可以显式覆盖进程的行为,以确保一致性。请参阅 移植说明 了解如何更新你的库。
- os.execl(path, arg0, arg1, …)
- os.execle(path, arg0, arg1, …, env)
- os.execlp(file, arg0, arg1, …)
- os.execlpe(file, arg0, arg1, …, env)
- os.execv(path, args)
- os.execve(path, args, env)
- os.execvp(file, args)
- os.execvpe(file, args, env)
- 这些函数都将执行一个新程序,以替换当前进程。它们没有返回值。在 Unix 上,新程序会加载到当前进程中,且进程号与调用者相同。过程中的错误会被报告为
OSError
异常。
当前进程会被立即替换。打开的文件对象和描述符都不会刷新,因此如果这些文件上可能缓冲了数据,则应在调用 exec*
函数之前使用 sys.stdout.flush()
或 os.fsync()
刷新它们。
exec*
函数的 "l" 和 "v" 变体的不同在于命令行参数的传递方式。 如果在编写代码时形参数量是固定的,则 "l" 变体可能是最方便的;单个形参简单地作为传给 execl*()
函数的额外形参即可。 当形参数量可变时则 "v" 变体更为好用,参数将以列表或元组的形式作为 args 形参传入。 在这两种情况下,传给子进程的参数应当以要运行的命令名称开头,但这不是强制性的。
在结尾位置包括 "p" 的变体形式 (execlp()
, execlpe()
, execvp()
和 execvpe()
) 将使用 PATH
环境变量来定位程序 file。 当环境被替换时 (使用某个 exec*e
变体形式,将在下一段中讨论),将使用新环境作为 PATH
变量的来源。 其他的变体形式 execl()
, execle()
, execv()
和 execve()
将不使用 PATH
变量来定位可执行程序;path 必须包含正确的绝对或相对路径。 相对路径必须包括至少一个斜杠,即使是在 Windows 上,因为简单名称将不会被解析。
对于 execle()
、execlpe()
、execve()
和 execvpe()
(都以 "e" 结尾),env 参数是一个映射,用于定义新进程的环境变量(代替当前进程的环境变量)。而函数 execl()
、execlp()
、execv()
和 execvp()
会将当前进程的环境变量过继给新进程。
某些平台上的 execve()
可以将 path 指定为打开的文件描述符。当前平台可能不支持此功能,可以使用 os.supports_fd
检查它是否支持。如果不可用,则使用它会抛出 NotImplementedError
异常。
引发一个 审计事件 os.exec
并附带参数 path
, args
, env
。
Availability: Unix, Windows, not WASI, not Android, not iOS.
在 3.3 版本发生变更: 新增支持将 execve()
的 path 参数指定为打开的文件描述符。
在 3.6 版本发生变更: 接受一个 path-like object。
- os._exit(n)
- 以状态码 n 退出进程,不会调用清理处理程序,不会刷新 stdio,等等。
备注
退出的标准方式是使用 sys.exit(n)
。 _exit()
通常只应在 fork()
所生成的子进程中使用。
以下是已定义的退出代码,可以用于 _exit()
,尽管它们不是必需的。这些退出代码通常用于 Python 编写的系统程序,例如邮件服务器的外部命令传递程序。
备注
其中部分退出代码在部分 Unix 平台上可能不可用,因为平台间存在差异。如果底层平台定义了这些常量,那上层也会定义。
- os.EX_OK
- 表示没有发生错误的退出码。 在某些平台上可能会从
EXIT_SUCCESS
定义的值中选取。 通常其值为零。
Availability: Unix, Windows.
- os.EX_USAGE
- 退出代码,表示命令使用不正确,如给出的参数数量有误。
Availability: Unix, not WASI.
- os.EX_DATAERR
- 退出代码,表示输入数据不正确。
Availability: Unix, not WASI.
- os.EX_NOINPUT
- 退出代码,表示某个输入文件不存在或不可读。
Availability: Unix, not WASI.
- os.EX_NOUSER
- 退出代码,表示指定的用户不存在。
Availability: Unix, not WASI.
- os.EX_NOHOST
- 退出代码,表示指定的主机不存在。
Availability: Unix, not WASI.
- os.EX_UNAVAILABLE
- 退出代码,表示所需的服务不可用。
Availability: Unix, not WASI.
- os.EX_SOFTWARE
- 退出代码,表示检测到内部软件错误。
Availability: Unix, not WASI.
- os.EX_OSERR
- 退出代码,表示检测到操作系统错误,例如无法 fork 或创建管道。
Availability: Unix, not WASI.
- os.EX_OSFILE
- 退出代码,表示某些系统文件不存在、无法打开或发生其他错误。
Availability: Unix, not WASI.
- os.EX_CANTCREAT
- 退出代码,表示无法创建用户指定的输出文件。
Availability: Unix, not WASI.
- os.EX_IOERR
- 退出代码,表示对某些文件进行读写时发生错误。
Availability: Unix, not WASI.
- os.EX_TEMPFAIL
- 退出代码,表示发生了暂时性故障。它可能并非意味着真正的错误,例如在可重试的情况下无法建立网络连接。
Availability: Unix, not WASI.
- os.EX_PROTOCOL
- 退出代码,表示协议交换是非法的、无效的或无法解读的。
Availability: Unix, not WASI.
- os.EX_NOPERM
- 退出代码,表示没有足够的权限执行该操作(但不适用于文件系统问题)。
Availability: Unix, not WASI.
- os.EX_CONFIG
- 退出代码,表示发生某种配置错误。
Availability: Unix, not WASI.
- os.EX_NOTFOUND
- 退出代码,表示的内容类似于“找不到条目”。
Availability: Unix, not WASI.
- os.fork()
- Fork 出一个子进程。在子进程中返回
0
,在父进程中返回子进程的进程号。如果发生错误,则抛出OSError
异常。
注意,当从线程中使用 fork()
时,某些平台(包括 FreeBSD <= 6.3 和 Cygwin)存在已知问题。
引发一个不带参数的 审计事件 os.fork
。
警告
如果你在调用fork()
的应用程序中使用 TLS 套接字,请参阅 ssl
文档中的警告信息。
警告
在 macOS 上将此函数与高层级的系统 API 混用是不安全的,包括 urllib.request
。
在 3.8 版本发生变更: 不再支持在子解释器中调用 fork()
(将抛出 RuntimeError
异常)。
在 3.12 版本发生变更: 如果 Python 能够检测到你的进程有多个线程,则 os.fork()
现在会引发 DeprecationWarning
。
在可以检测时,我们选择将此显示为警告,以便更好地告知开发人员 POSIX 平台明确指出不支持的设计问题。 在 POSIX 平台上即使在 看起来 可行的代码中,将线程与 os.fork()
混用也是不安全的。 当父进程中存在线程时 CPython 运行时本身总是会在子进程中执行不安全的 API 调用 (如 malloc
和 free
)。
使用 macOS 的用户或使用 glibc 中可找到的典型实现以外的 libc 或 malloc 实现的用户在运行此类代码时更容易发生死锁现象。
请参阅 有关 fork 与线程不兼容的讨论 [https://discuss.python.org/t/33555] 了解我们为何向开发者公开这个长期存在的平台不兼容性问题的技术细节。
Availability: POSIX, not WASI, not Android, not iOS.
- os.forkpty()
- Fork 出一个子进程,使用新的伪终端作为子进程的控制终端。返回一对
(pid, fd)
,其中 pid 在子进程中为0
,这是父进程中新子进程的进程号,而 fd 是伪终端主设备的文件描述符。对于更便于移植的方法,请使用pty
模块。如果发生错误,则抛出OSError
异常。
引发一个不带参数的 审计事件 os.forkpty
。
警告
在 macOS 上将此函数与高层级的系统 API 混用是不安全的,包括 urllib.request
。
在 3.8 版本发生变更: 不再支持在子解释器中调用 forkpty()
(将抛出 RuntimeError
异常)。
在 3.12 版本发生变更: 现在如果 Python 能够检测到你的进程有多个线程,此函数将引发 DeprecationWarning
。 请参阅有关 os.fork()
的更详细解释。
Availability: Unix, not WASI, not Android, not iOS.
- os.kill(pid, sig, /)
- 将信号 sig 发送至进程 pid。特定平台上可用的信号常量定义在
signal
模块中。
Windows: signal.CTRL_C_EVENT
和 signal.CTRL_BREAK_EVENT
信号是只能被发送给共享同一个控制台窗口的控制台进程例如某些子进程的特殊信号。 任何其他的 sig 值都将导致进程被 TerminateProcess API 无条件地杀掉,且退出码将被设为 sig。
另请参阅 signal.pthread_kill()
。
引发一个 审计事件 os.kill
并附带参数 pid
, sig
。
Availability: Unix, Windows, not WASI, not iOS.
在 3.2 版本发生变更: 添加了对 Windows 的支持。
- os.killpg(pgid, sig, /)
- 将信号 sig 发送给进程组 pgid。
引发一个 审计事件 os.killpg
并附带参数 pgid
, sig
。
Availability: Unix, not WASI, not iOS.
- os.nice(increment, /)
- 将进程的优先级(nice 值)增加 increment,返回新的 nice 值。
Availability: Unix, not WASI.
- os.pidfd_open(pid, flags=0)
- 返回一个指向设置了 flags 的进程 pid 的文件描述符。 该描述符可用于执行无需竞争和信号的进程管理。
更多详细信息请参阅 pidfd_open(2)) [https://manpages.debian.org/pidfd_open(2)] 手册页。
Availability: Linux >= 5.3, Android >= build-time
API level 31
Added in version 3.9.
- os.PIDFD_NONBLOCK
- 该旗标表示文件描述符将是非阻塞的。 如果文件描述符所引用的进程尚未终止,那么尝试使用 waitid(2)) [https://manpages.debian.org/waitid(2)] 等待文件描述符将立即返回错误
EAGAIN
而不是阻塞。
Availability: Linux >= 5.10
Added in version 3.12.
- os.plock(op, /)
- 将程序段锁定到内存中。op 的值(定义在
中)决定了哪些段被锁定。
Availability: Unix, not WASI, not iOS.
- os.popen(cmd, mode='r', buffering=-1)
- 打开一个通往或接受命令 cmd 的管道。 返回值是连接到该管道的已打开文件对象,它可读取还是可写入取决于其 mode 是
'r'
(默认) 还是'w'
。 buffering 参数与内置open()
函数相应的参数含义相同。 返回的文件对象只能读写文本字符串而不是字节串。
如果子进程成功退出,则 close
方法返回 None
。如果发生错误,则返回子进程的返回码。在 POSIX 系统上,如果返回码为正,则它就是进程返回值左移一个字节后的值。如果返回码为负,则进程是被信号终止的,返回码取反后就是该信号。(例如,如果子进程被终止,则返回值可能是 - signal.SIGKILL
。)在 Windows 系统上,返回值包含子进程的返回码(有符号整数)。
在 Unix 上,waitstatus_to_exitcode()
可以将 close
方法的返回值(即退出状态,不能是 None
)转换为退出码。在 Windows 上,close
方法的结果直接就是退出码(或 None
)。
本方法是使用 subprocess.Popen
实现的,如需更强大的方法来管理和沟通子进程,请参阅该类的文档。
Availability: not WASI, not Android, not iOS.
备注
Python UTF-8 模型 影响 cmd 和管道内容所使用的编码格式。
popen()
是针对 subprocess.Popen
的简单包装器。 请使用 subprocess.Popen
或 subprocess.run()
来控制编码格式等选项。
- os.posix_spawn(path, argv, env, *, file_actions=None, setpgroup=None, resetids=False, setsid=False, setsigmask=(), setsigdef=(), scheduler=None)
- 包装
posix_spawn()
C 库 API 以供 Python 使用。
大多数用户应使用 subprocess.run()
代替 posix_spawn()
。
位置参数 path, args 和 env 与 execve()
类似。 env 允许为 None
,在此情况下将使用当前进程的环境。
path 形参是可执行文件的路径,path 中应当包含目录。 使用 posix_spawnp()
可传入不带目录的可执行文件。
file_actions 参数可以是由元组组成的序列,序列描述了对子进程中指定文件描述符采取的操作,这些操作会在 C 库实现的 fork()
和 exec()
步骤间完成。每个元组的第一个元素必须是下面列出的三个类型指示符之一,用于描述元组剩余的元素:
- os.POSIX_SPAWN_OPEN
(
os.POSIX_SPAWN_OPEN
, fd, path, flags, mode) 执行os.dup2(os.open(path, flags, mode), fd)
。os.POSIX_SPAWN_CLOSE
(
os.POSIX_SPAWN_CLOSE
, fd) 执行os.close(fd)
。os.POSIX_SPAWN_DUP2
(
os.POSIX_SPAWN_DUP2
, fd, new_fd) 执行os.dup2(fd, new_fd)
。os.POSIX_SPAWN_CLOSEFROM
- (
os.POSIX_SPAWN_CLOSEFROM
, fd) 执行os.closerange(fd, INF)
。
这些元组对应于 C 库 posix_spawn_file_actions_addopen()
, posix_spawn_file_actions_addclose()
, posix_spawn_file_actions_adddup2()
和 posix_spawn_file_actions_addclosefrom_np()
API 调用,用于为 posix_spawn()
调用本身做准备。
setpgroup 参数将把子进程的进程组设置为指定值。 如果指定值为 0,则子进程的进程组 ID 将与其进程 ID 相同。 如果未设置 setpgroup 的值,则子进程将继承父进程的进程组 ID。 本参数对应于 C 库的 POSIX_SPAWN_SETPGROUP
旗标。
如果 resetids 参数为 True
则它会将子进程的有效 UID 和 GID 重置为父进程的实际 UID 和 GID。 如果该参数为 False
,则子进程会保留父进程的有效 UID 和 GID。 无论哪种情况,如果在可执行文件上启用了设置用户 ID 和设置组 ID 权限位,它们的效果将覆盖有效 UID 和 GID 的设置。 本参数对应于 C 库的 POSIX_SPAWN_RESETIDS
旗标。
如果 setsid 参数为 True
,它将为 posix_spawn
新建一个会话 ID。 setsid 需要 POSIX_SPAWN_SETSID
或 POSIX_SPAWN_SETSID_NP
旗标。 否则,将会引发 NotImplementedError
。
setsigmask 参数会将信号掩码设置为指定的信号集合。 如果未使用该参数,则子进程将继承父进程的信号掩码。 本参数对应于 C 库的 POSIX_SPAWN_SETSIGMASK
旗标。
sigdef 参数会将集合中所有信号的操作全部重置为默认。 本参数对应于 C 库的 POSIX_SPAWN_SETSIGDEF
旗标。
scheduler 参数必须是一个元组,其中包含(可选的)调度器策略以及携带了调度器参数的 sched_param
实例。 在调度器策略所在位置的值为 None
表示未提供该值。 本参数是 C 库的 POSIX_SPAWN_SETSCHEDPARAM
和 POSIX_SPAWN_SETSCHEDULER
旗标的组合。
引发一个 审计事件 os.posix_spawn
并附带参数 path
, argv
, env
。
Added in version 3.8.
在 3.13 版本发生变更: env 形参可接受 None
。 os.POSIX_SPAWN_CLOSEFROM
在具有 posix_spawn_file_actions_addclosefrom_np()
的平台上可用。
Availability: Unix, not WASI, not Android, not iOS.
- os.posix_spawnp(path, argv, env, *, file_actions=None, setpgroup=None, resetids=False, setsid=False, setsigmask=(), setsigdef=(), scheduler=None)
- 包装
posix_spawnp()
C 库 API 以供 Python 使用。
与 posix_spawn()
相似,但是系统会在 PATH
环境变量指定的目录列表中搜索可执行文件 executable (与 execvp(3)
相同)。
引发一个 审计事件 os.posix_spawn
并附带参数 path
, argv
, env
。
Added in version 3.8.
Availability: POSIX, not WASI, not Android, not iOS.
参见 posix_spawn()
文档。
- os.register_at_fork(*, before=None, after_in_parent=None, after_in_child=None)
注册可调用对象,在使用
os.fork()
或类似的进程克隆 API 派生新的子进程时,这些对象会运行。参数是可选的,且为仅关键字 (Keyword-only) 参数。每个参数指定一个不同的调用点。before 是一个函数,在 fork 子进程前调用。
after_in_parent 是一个函数,在 fork 子进程后从父进程调用。
after_in_child 是一个函数,从子进程中调用。
只有希望控制权回到 Python 解释器时,才进行这些调用。典型的 子进程
启动时不会触发它们,因为子进程不会重新进入解释器。
在注册的函数中,用于 fork 前运行的函数将按与注册相反的顺序调用。用于 fork 后(从父进程或子进程)运行的函数按注册顺序调用。
注意,第三方 C 代码的 fork()
调用可能不会调用这些函数,除非它显式调用了 PyOS_BeforeFork()
、PyOS_AfterFork_Parent()
和 PyOS_AfterFork_Child()
。
函数注册后无法注销。
Availability: Unix, not WASI, not Android, not iOS.
Added in version 3.7.
- os.spawnl(mode, path, …)
- os.spawnle(mode, path, …, env)
- os.spawnlp(mode, file, …)
- os.spawnlpe(mode, file, …, env)
- os.spawnv(mode, path, args)
- os.spawnve(mode, path, args, env)
- os.spawnvp(mode, file, args)
- os.spawnvpe(mode, file, args, env)
- 在新进程中执行程序 path。
(注意,subprocess
模块提供了更强大的工具来生成新进程并跟踪执行结果,使用该模块比使用这些函数更好。尤其应当检查 使用 subprocess 模块替换旧函数 部分。)
mode 为 P_NOWAIT
时,本函数返回新进程的进程号。mode 为 P_WAIT
时,如果进程正常退出,返回退出代码,如果被终止,返回 -signal
,其中 signal 是终止进程的信号。在 Windows 上,进程号实际上是进程句柄,因此可以与 waitpid()
函数一起使用。
注意在 VxWorks 上,新进程被终止时,本函数不会返回 -signal
,而是会抛出 OSError 异常。
spawn*
函数的 "l" 和 "v" 变体的不同在于命令行参数的传递方式。 如果在编写代码时形参数量是固定的,则 "l" 变体可能是最方便的;单个形参简单地作为传给 spawnl*()
函数的额外形参即可。 当形参数量可变时 "v" 变体更为好用,参数将以列表或元组的形式作为 args 形参传入。 在这两种情况下,传给子进程的参数应当以要运行的命令名称开头。
结尾包含第二个 "p" 的变体(spawnlp()
、spawnlpe()
、spawnvp()
和 spawnvpe()
)将使用 PATH
环境变量来查找程序 file。当环境被替换时(使用下一段讨论的 spawn*e
变体之一), PATH
变量将来自于新环境。其他变体 spawnl()
、spawnle()
、spawnv()
和 spawnve()
不使用 PATH
变量来查找程序,因此 path 必须包含正确的绝对或相对路径。
对于 spawnle()
、spawnlpe()
、spawnve()
和 spawnvpe()
(都以 "e" 结尾),env 参数是一个映射,用于定义新进程的环境变量(代替当前进程的环境变量)。而函数 spawnl()
、spawnlp()
、spawnv()
和 spawnvp()
会将当前进程的环境变量过继给新进程。注意,env 字典中的键和值必须是字符串。无效的键或值将导致函数出错,返回值为 127
。
例如,以下对 spawnlp()
和 spawnvpe()
的调用是等效的:
- import os
- os.spawnlp(os.P_WAIT, 'cp', 'cp', 'index.html', 'devnull')
- L = ['cp', 'index.html', 'devnull']
- os.spawnvpe(os.P_WAIT, 'cp', L, os.environ)
引发一个 审计事件 os.spawn
并附带参数 mode
, path
, args
, env
。
Availability: Unix, Windows, not WASI, not Android, not iOS.
spawnlp()
, spawnlpe()
, spawnvp()
和 spawnvpe()
在 Windows 上不可用。 spawnle()
和 spawnve()
在 Windows 上不是线程安全的;我们建议你用 subprocess
模块来代替。
在 3.6 版本发生变更: 接受一个 path-like object。
- os.P_NOWAIT
- os.P_NOWAITO
- 传给
spawn*
函数族的 mode 形参可能的值。 如果给出这些值中的某一个,则spawn*
函数将在新进程创建后立即返回,并将进程 ID 作为返回值。
Availability: Unix, Windows.
- os.P_WAIT
- 传给
spawn*
函数族的 mode 形参可能的值。 如果作为 mode 给出,则spawn*
函数将在新进程运行完毕后才返回,并在进程运行成功时返回退出码,或者如果进程被信号杀掉则返回-signal
。
Availability: Unix, Windows.
- os.P_DETACH
- os.P_OVERLAY
spawn*
系列函数的 mode 参数的可取值。它们比上面列出的值可移植性差。P_DETACH
与P_NOWAIT
相似,但是新进程会与父进程的控制台脱离。使用P_OVERLAY
则会替换当前进程,spawn*
函数将不会返回。
Availability: Windows.
- os.startfile(path[, operation][, arguments][, cwd][, show_cmd])
- 使用已关联的应用程序打开文件。
当未指定 operation 时,这类似于在 Windows 资源管理器中双击文件,或在交互式命令行中将文件名作为 start 命令的参数:通过扩展名所关联的应用程序(如果有的话)来打开文件。
当指定其他 operation 时,它必须是一个对该文件执行操作的“命令动词”。 Microsoft 文档中记录的常用动词有 'open'
, 'print'
和 'edit'
(用于文件) 以及 'explore'
和 'find'
(用于目录)。
在启动某个应用程序时,arguments 将作为一个字符串传入。若是打开某个文档,此参数可能没什么效果。
默认工作目录是继承而来的,但可以通过 cwd 参数进行覆盖。且应为绝对路径。相对路径 path 将据此参数进行解析。
使用 show_cmd 覆盖默认的窗口样式。 这是否生效则取决于被启动的应用程序。 其值应为 Win32 ShellExecute()
函数所支持的整数形式。
在关联的应用程序启动后,startfile()
就会立即返回。 没有提供等待应用程序关闭的选项,也没有办法获得应用程序的退出状态。 path 形参是基于当前目录或 cwd 的相对路径。 如果要使用绝对路径,请确保第一个字符不为斜杠 ('/'
) 。 请用 pathlib
或 os.path.normpath()
函数来保证路径已按照 Win32 的要求进行了正确的编码。
为了减少解释器的启动开销,Win32 ShellExecute()
函数将不会被解析直到该函数首次被调用。 如果该函数无法被解析,则将引发 NotImplementedError
异常。
引发一个 审计事件 os.startfile
并附带参数 path
, operation
。
引发一个 审计事件 os.startfile/2
并附带参数 path
, operation
, arguments
, cwd
, show_cmd
。
Availability: Windows.
在 3.10 版本发生变更: 加入了 arguments、cwd 和 show_cmd 参数,以及 os.startfile/2
审计事件。
- os.system(command)
- 在子外壳程序中执行此命令(一个字符串)。 这是通过调用标准 C 函数
system()
来实现的,并受到同样的限制。 对sys.stdin
的更改等不会反映在所执行命令的环境中。 如果 command 生成了任何输出,它将被发送到解释器的标准输出流。 C 标准没有指明这个 C 函数返回值的含义,因此这个 Python 函数的返回值取决于具体系统。
在 Unix 上,返回值为进程的退出状态,以针对 wait()
而指定的格式进行编码。
在 Windows 上,返回值是运行 command 后系统 Shell 返回的值。该 Shell 由 Windows 环境变量 COMSPEC
: 给出:通常是 cmd.exe,它会返回命令的退出状态。在使用非原生 Shell 的系统上,请查阅 Shell 的文档。
subprocess
模块提供了更强大的工具来生成新进程并跟踪执行结果,使用该模块比使用本函数更好。参阅 subprocess
文档中的 使用 subprocess 模块替换旧函数 部分以获取有用的帮助。
在 Unix 上,waitstatus_to_exitcode()
可以将返回值(即退出状态)转换为退出码。在 Windows 上,返回值就是退出码。
引发一个 审计事件 os.system
并附带参数 command
。
Availability: Unix, Windows, not WASI, not Android, not iOS.
- os.times()
返回当前的全局进程时间。返回值是一个有 5 个属性的对象:
user
- 用户时间system
- 系统时间children_user
- 所有子进程的用户时间children_system
- 所有子进程的系统时间elapsed
- 从过去的固定时间点起,经过的真实时间
为了向后兼容,该对象的行为也类似于五元组,按照 user
,system
,children_user
,children_system
和 elapsed
顺序组成。
在 Unix 上请参阅 Unix 手册页 times(2)) [https://manpages.debian.org/times(2)] 和 times(3)) [https://man.freebsd.org/cgi/man.cgi?time(3)] 而在 Windows 上请参阅 GetProcessTimes MSDN [https://docs.microsoft.com/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesstimes]。 在 Windows 上,只有 user
和 system
是已知的;其他属性均为零。
Availability: Unix, Windows.
在 3.3 版本发生变更: 返回结果的类型由元组变成一个类似元组的对象,同时具有命名的属性。
- os.wait()
- 等待子进程执行完毕,返回一个元组,包含其 pid 和退出状态指示:一个 16 位数字,其低字节是终止该进程的信号编号,高字节是退出状态码(信号编号为零的情况下),如果生成了核心文件,则低字节的高位会置位。
如果不存在可被等待的子进程,则将引发 ChildProcessError
。
可以使用 waitstatus_to_exitcode()
来将退出状态转换为退出码。
Availability: Unix, not WASI, not Android, not iOS.
参见
下面列出的其他 wait*()
函数可被用于等待特定子进程完成并具有更多的选项。 waitpid()
是其中唯一在 Windows 上也可用的。
- os.waitid(idtype, id, options, /)
- 等待一个子进程完成。
idtype 可以为 P_PID
, P_PGID
, P_ALL
或 (在 Linux 上) P_PIDFD
。 对于 id 的解读由它来决定;请参阅它们各自的说明。
options 是多个旗标的 OR 组合。 要求至少有 WEXITED
, WSTOPPED
或 WCONTINUED
中的一个;WNOHANG
和 WNOWAIT
是附加的可选旗标。
返回值是一个代表 siginfo_t
结构体所包含数据的对象,具有以下属性:
si_pid
(进程 ID)si_uid
(子进程的实际用户 ID)si_signo
(始终为SIGCHLD
)si_status
(退出状态或信号编号,具体取决于si_code
)si_code
(可能的值参见CLD_EXITED
)
如果指定了 WNOHANG
而在所请求的状态中没有匹配的子进程,则将返回 None
。 在其他情况下,如果没有匹配的子进程可被等待,则将引发 ChildProcessError
。
Availability: Unix, not WASI, not Android, not iOS.
Added in version 3.3.
在 3.13 版本发生变更: 现在该函数在 macOS 同样可用。
- os.waitpid(pid, options, /)
- 本函数的细节在 Unix 和 Windows 上有不同之处。
在 Unix 上:等待进程号为 pid 的子进程执行完毕,返回一个元组,内含其进程 ID 和退出状态指示(编码与 wait()
相同)。调用的语义受整数 options 的影响,常规操作下该值应为 0
。
如果 pid 大于 0
,则 waitpid()
会获取该指定进程的状态信息。如果 pid 为 0
,则获取当前进程所在进程组中的所有子进程的状态。如果 pid 为 -1
,则获取当前进程的子进程状态。如果 pid 小于 -1
,则获取进程组 -pid
( pid 的绝对值)中所有进程的状态。
options 是多个旗标的 OR 组合。 如果它包含了 WNOHANG
并且在所请求的状态中没有匹配的子进程,则将返回 (0, 0)
。 在其他情况下,如果没有匹配的子进程可以被等待,则将引发 ChildProcessError
。 其他的可用选项还有 WUNTRACED
和 WCONTINUED
。
在 Windows 上:等待句柄为 pid 的进程执行完毕,返回一个元组,内含 pid 以及左移 8 位后的退出状态码(移位简化了跨平台使用本函数)。小于或等于 0
的 pid 在 Windows 上没有特殊含义,且会抛出异常。整数值 options 无效。pid 可以指向任何 ID 已知的进程,不一定是子进程。调用 spawn*
函数时传入 P_NOWAIT
将返回合适的进程句柄。
可以使用 waitstatus_to_exitcode()
来将退出状态转换为退出码。
Availability: Unix, Windows, not WASI, not Android, not iOS.
在 3.5 版本发生变更: 如果系统调用被中断,但信号处理程序没有触发异常,此函数现在会重试系统调用,而不是触发 InterruptedError
异常 (原因详见 PEP 475 [https://peps.python.org/pep-0475/])。
- os.wait3(options)
- 与
waitpid()
类似,区别在于没有给出进程 id 参数并且返回一个 3 元组,其中包括子进程的 id、退出状态指示以及资源使用信息。 请参阅resource.getrusage()
了解有关资源使用信息的详情。 options 参数与提供给waitpid()
和wait4()
的相同。
可以使用 waitstatus_to_exitcode()
来将退出状态转换为退出码。
Availability: Unix, not WASI, not Android, not iOS.
- os.wait4(pid, options)
- 与
waitpid()
类似,区别在于它是返回一个 3 元组,其中包括子进程的 id、退出状态指示以及资源使用信息。 请参阅resource.getrusage()
了解有关资源使用信息的详情。wait4()
的参数与提供给waitpid()
的相同。
可以使用 waitstatus_to_exitcode()
来将退出状态转换为退出码。
Availability: Unix, not WASI, not Android, not iOS.
- os.P_PID
- os.P_PGID
- os.P_ALL
- os.P_PIDFD
这些是
waitid()
中 idtype 可取的值。 它们会影响 id 的解读方式:P_PID
- 等待 PID 为 id 的子进程。P_PGID
- 等待进程组 ID 为 id 的任何子进程。P_ALL
- 等待任何子进程;id 会被忽略。P_PIDFD
- 等待以文件描述符 id 作为标识的子进程(使用a process file descriptor created withpidfd_open()
创建的进程文件描述符)。
Availability: Unix, not WASI, not Android, not iOS.
备注
P_PIDFD
仅在 Linux >= 5.4 时可用。
Added in version 3.3.
Added in version 3.9: P_PIDFD
常量。
- os.WCONTINUED
- 如果子进程自它们上次被报告之后从作业控制停止位置继续执行,则
waitpid()
,wait3()
,wait4()
和waitid()
的这个 选项 旗标将导致子进程被报告。
Availability: Unix, not WASI, not Android, not iOS.
- os.WEXITED
waitid()
的这个 选项 旗标将导致已终结的子进程被报告。
其他 wait*
函数总是会报告已终结的子进程,所以此选项对它们不可用。
Availability: Unix, not WASI, not Android, not iOS.
Added in version 3.3.
- os.WSTOPPED
- 这个
waitid()
的 选项 旗标将导致被信号发送所停止的子进程被报告。
这个选项对于其他 wait*
函数不可用。
Availability: Unix, not WASI, not Android, not iOS.
Added in version 3.3.
这个选项对于 waitid()
不可用。
Availability: Unix, not WASI, not Android, not iOS.
Availability: Unix, not WASI, not Android, not iOS.
- os.WNOWAIT
- 这个 选项 旗标将导致
waitid()
以可等待的状态离开子进程,这样后续的wait*()
调用可被用来再次获取子进程状态信息。
这个选项对于其他 wait*
函数不可用。
Availability: Unix, not WASI, not Android, not iOS.
- os.CLD_EXITED
- os.CLD_KILLED
- os.CLD_DUMPED
- os.CLD_TRAPPED
- os.CLD_STOPPED
- os.CLD_CONTINUED
- 这些是由
waitid()
所返回的结果中si_code
可能的取值。
Availability: Unix, not WASI, not Android, not iOS.
Added in version 3.3.
在 3.9 版本发生变更: 添加了 CLD_KILLED
和 CLD_STOPPED
值。
- os.waitstatus_to_exitcode(status)
- 将等待状态转换为退出码。
在 Unix 上:
如果进程正常退出(当
WIFEXITED(status)
为真值),则返回进程退出状态 (返回WEXITSTATUS(status)
): 结果值大于等于 0。如果进程被信号终止(当
WIFSIGNALED(status)
为真值),则返回-signum
其中 signum 为导致进程终止的信号数值 (返回-WTERMSIG(status)
): 结果值小于 0。否则将抛出
ValueError
异常。
在 Windows 上,返回 status 右移 8 位的结果。
在 Unix 上,如果进程正被追踪或 waitpid()
附带 WUNTRACED
选项被调用,则调用者必须先检查 WIFSTOPPED(status)
是否为真值。 如果 WIFSTOPPED(status)
为真值则此函数不可被调用。
参见
WIFEXITED()
, WEXITSTATUS()
, WIFSIGNALED()
, WTERMSIG()
, WIFSTOPPED()
, WSTOPSIG()
函数。
Availability: Unix, Windows, not WASI, not Android, not iOS.
Added in version 3.9.
下列函数采用进程状态码作为参数,状态码由 system()
、wait()
或 waitpid()
返回。它们可用于确定进程上发生的操作。
- os.WCOREDUMP(status, /)
- 如果为该进程生成了核心转储,返回
True
,否则返回False
。
此函数应当仅在 WIFSIGNALED()
为真值时使用。
Availability: Unix, not WASI, not Android, not iOS.
- os.WIFCONTINUED(status)
- 如果一个已停止的子进程通过传送
SIGCONT
获得恢复(如果该进程是从任务控制停止后再继续的)则返回True
,否则返回False
。
参见 WCONTINUED
选项。
Availability: Unix, not WASI, not Android, not iOS.
- os.WIFSTOPPED(status)
- 如果进程是通过传送一个信号来停止的则返回
True
,否则返回False
。
WIFSTOPPED()
只有在当 waitpid()
调用是通过使用 WUNTRACED
选项来完成或者当该进程正被追踪时 (参见 ptrace(2)) [https://manpages.debian.org/ptrace(2)]) 才返回 True
。
Availability: Unix, not WASI, not Android, not iOS.
- os.WIFSIGNALED(status)
- 如果进程是通过一个信号来终止的则返回
True
,否则返回False
。
Availability: Unix, not WASI, not Android, not iOS.
- os.WIFEXITED(status)
- 如果进程正常终止退出则返回
True
,也就是说通过调用exit()
或_exit()
,或者通过从main()
返回;在其他情况下则返回False
。
Availability: Unix, not WASI, not Android, not iOS.
- os.WEXITSTATUS(status)
- 返回进程退出状态。
此函数应当仅在 WIFEXITED()
为真值时使用。
Availability: Unix, not WASI, not Android, not iOS.
- os.WSTOPSIG(status)
- 返回导致进程停止的信号。
此函数应当仅在 WIFSTOPPED()
为真值时使用。
Availability: Unix, not WASI, not Android, not iOS.
- os.WTERMSIG(status)
- 返回导致进程终止的信号的编号。
此函数应当仅在 WIFSIGNALED()
为真值时使用。
Availability: Unix, not WASI, not Android, not iOS.
调度器接口
这些函数控制操作系统如何为进程分配 CPU 时间。 它们仅在某些 Unix 平台上可用。 更多细节信息请查阅你所用 Unix 的指南页面。
Added in version 3.3.
以下调度策略如果被操作系统支持就会对外公开。
- os.SCHED_OTHER
- 默认调度策略。
- os.SCHED_BATCH
- 用于 CPU 密集型进程的调度策略,它会尽量为计算机中的其余任务保留交互性。
- os.SCHED_IDLE
- 用于极低优先级的后台任务的调度策略。
- os.SCHED_SPORADIC
- 用于偶发型服务程序的调度策略。
- os.SCHED_FIFO
- 先进先出的调度策略。
- os.SCHED_RR
- 循环式的调度策略。
- os.SCHED_RESET_ON_FORK
- 此旗标可与任何其他调度策略进行 OR 运算。 当带有此旗标的进程设置分叉时,其子进程的调度策略和优先级会被重置为默认值。
- class os.sched_param(sched_priority)
- 这个类表示在
sched_setparam()
,sched_setscheduler()
和sched_getparam()
中使用的可修改调度形参。 它属于不可变对象。
目前它只有一个可能的形参:
- sched_priority
- 一个调度策略的调度优先级。
- os.sched_get_priority_min(policy)
- 获取 policy 的最低优先级数值。 policy 是以上调度策略常量之一。
- os.sched_get_priority_max(policy)
- 获取 policy 的最高优先级数值。 policy 是以上调度策略常量之一。
- os.sched_setscheduler(pid, policy, param, /)
- 设置 PID 为 pid 的进程的调度策略。pid 为 0 指的是调用本方法的进程。policy 是以上调度策略常量之一。param 是一个
sched_param
实例。
- os.sched_getscheduler(pid, /)
- 返回 PID 为 pid 的进程的调度策略。pid 为 0 指的是调用本方法的进程。返回的结果是以上调度策略常量之一。
- os.sched_setparam(pid, param, /)
- 设置 PID 为 pid 的进程的调度参数。 pid 为 0 表示调用方过程。 param 是一个
sched_param
实例。
- os.sched_getparam(pid, /)
- 返回 PID 为 pid 的进程的调度参数为一个
sched_param
实例。pid 为 0 指的是调用本方法的进程。
- os.sched_rr_get_interval(pid, /)
- 返回 PID 为 pid 的进程在时间片轮转调度下的时间片长度(单位为秒)。pid 为 0 指的是调用本方法的进程。
- os.sched_yield()
- 主动让出 CPU。 请参阅 sched_yield(2)) [https://manpages.debian.org/sched_yield(2)] 了解详情。
- os.sched_setaffinity(pid, mask, /)
- 将 PID 为 pid 的进程(为零则为当前进程)限制到一组 CPU 上。mask 是整数的可迭代对象,表示应将进程限制在其中的一组 CPU。
- os.sched_getaffinity(pid, /)
- 返回 PID 为 pid 的进程被限制到的那一组 CPU。
如果 pid 为零,则返回当前进程的调用方线程被限制到的那一组 CPU。
另请参阅 process_cpu_count()
函数。
其他系统信息
- os.confstr(name, /)
- 返回字符串格式的系统配置信息。name 指定要查找的配置名称,它可以是字符串,是一个系统已定义的名称,这些名称定义在不同标准(POSIX,Unix 95,Unix 98 等)中。一些平台还定义了额外的其他名称。当前操作系统已定义的名称在
confstr_names
字典的键中给出。对于未包含在该映射中的配置名称,也可以传递一个整数作为 name。
如果 name 指定的配置值未定义,返回 None
。
如果 name 是一个字符串且不是已定义的名称,将抛出 ValueError
异常。如果当前系统不支持 name 指定的配置名称,即使该名称存在于 confstr_names
,也会抛出 OSError
异常,错误码为 errno.EINVAL
。
Availability: Unix.
- os.confstr_names
- 字典,表示映射关系,为
confstr()
可接受名称与操作系统为这些名称定义的整数值之间的映射。这可用于判断系统已定义了哪些名称。
Availability: Unix.
- os.cpu_count()
- 返回 系统 中逻辑 CPU 的数量。 如果无法确定则返回
None
。
process_cpu_count()
函数可被用于获取 当前进程 的调用方线程可以使用的逻辑 CPU 数量。
Added in version 3.4.
在 3.13 版本发生变更: 如果给出了 -X cpu_count
或设置了 PYTHON_CPU_COUNT
,则 cpu_count()
将返回被覆盖的值 n。
- os.getloadavg()
- 返回系统运行队列中最近 1、5 和 15 分钟内的平均进程数。无法获得平均负载则抛出
OSError
异常。
Availability: Unix.
- os.process_cpu_count()
- 获取 当前进程 的调用方线程可以使用的逻辑 CPU 数量。 如果无法确定则返回
None
。 根据实际 CPU 的关联性它可能会小于cpu_count()
。
cpu_count()
函数可被用于获取 系统 中逻辑 CPU 的数量。
如果给出了 -X cpu_count
或设置了 PYTHON_CPU_COUNT
,则 process_cpu_count()
将返回被覆盖的值 n。
另请参阅 sched_getaffinity()
函数。
Added in version 3.13.
- os.sysconf(name, /)
- 返回整数格式的系统配置信息。如果 name 指定的配置值未定义,返回
-1
。对confstr()
的 name 参数的注释在此处也适用。当前已知的配置名称在sysconf_names
字典中提供。
Availability: Unix.
- os.sysconf_names
- 字典,表示映射关系,为
sysconf()
可接受名称与操作系统为这些名称定义的整数值之间的映射。这可用于判断系统已定义了哪些名称。
Availability: Unix.
在 3.11 版本发生变更: 添加 'SC_MINSIGSTKSZ'
名称。
以下数据值用于支持对路径本身的操作。所有平台都有定义。
对路径的高级操作在 os.path
模块中定义。
- os.curdir
- 操作系统用来表示当前目录的常量字符串。在 Windows 和 POSIX 上是
'.'
。在os.path
中也可用。
- os.pardir
- 操作系统用来表示父目录的常量字符串。在 Windows 和 POSIX 上是
'..'
。在os.path
中也可用。
- os.sep
- 操作系统用来分隔路径不同部分的字符。在 POSIX 上是
'/'
,在 Windows 上是是'\'
。注意,仅了解它不足以能解析或连接路径,请使用os.path.split()
和os.path.join()
,但它有时是有用的。在os.path
中也可用。
- os.altsep
- 操作系统用来分隔路径不同部分的替代字符。如果仅存在一个分隔符,则为
None
。在sep
是反斜杠的 Windows 系统上,该值被设为'/'
。在os.path
中也可用。
- os.extsep
- 分隔基本文件名与扩展名的字符,如
os.py
中的'.'
。在os.path
中也可用。
- os.pathsep
- 操作系统通常用于分隔搜索路径(如
PATH
)中不同部分的字符,如 POSIX 上是':'
,Windows 上是';'
。在os.path
中也可用。
- os.linesep
- 当前平台用于分隔(或终止)行的字符串。它可以是单个字符,如 POSIX 上是
'\n'
,也可以是多个字符,如 Windows 上是'\r\n'
。在写入以文本模式(默认模式)打开的文件时,请不要使用 os.linesep 作为行终止符,请在所有平台上都使用一个'\n'
代替。
- os.devnull
- 空设备的文件路径。如 POSIX 上为
'devnull'
,Windows 上为'nul'
。在os.path
中也可用。
- os.RTLD_LAZY
- os.RTLD_NOW
- os.RTLD_GLOBAL
- os.RTLD_LOCAL
- os.RTLD_NODELETE
- os.RTLD_NOLOAD
- os.RTLD_DEEPBIND
setdlopenflags()
和getdlopenflags()
函数所使用的标志。请参阅 Unix 手册页 dlopen(3)) [https://manpages.debian.org/dlopen(3)] 获取不同标志的含义。
Added in version 3.3.
随机数
- os.getrandom(size, flags=0)
- 获得最多为 size 的随机字节。本函数返回的字节数可能少于请求的字节数。
这些字节可用于为用户空间的随机数生成器提供种子,或用于加密目的。
getrandom()
依赖于从设备驱动程序和其他环境噪声源收集的熵。不必要地读取大量数据将对使用 devrandom
和 devurandom
设备的其他用户产生负面影响。
flags 参数是一个位掩码,它可以包含零个或多个下列值的或运算结果: os.GRND_RANDOM
和 GRND_NONBLOCK
。
另请参阅 Linux getrandom() 手册页 [https://man7.org/linux/manpages/man2/getrandom.2.html]。
Availability: Linux >= 3.17.
Added in version 3.6.
- os.urandom(size, /)
- 返回大小为 size 的字节串,它是适合加密使用的随机字节。
本函数从系统指定的随机源获取随机字节。对于加密应用程序,返回的数据应有足够的不可预测性,尽管其确切的品质取决于操作系统的实现。
在 Linux 上,如果 getrandom()
系统调用可用,它将以阻塞模式使用:阻塞直到系统的 urandom 熵池初始化完毕(内核收集了 128 位熵)。原理请参阅 PEP 524 [https://peps.python.org/pep-0524/]。在 Linux 上,getrandom()
可以以非阻塞模式(使用 GRND_NONBLOCK
标志)获取随机字节,或者轮询直到系统的 urandom 熵池初始化完毕。
在类 Unix 系统上,随机字节是从 devurandom
设备读取的。如果 devurandom
设备不可用或不可读,则抛出 NotImplementedError
异常。
在 Windows 上,它将使用 BCryptGenRandom()
。
参见
secrets
模块提供了更高级的功能。所在平台会提供随机数生成器,有关其易于使用的接口,请参阅 random.SystemRandom
。
在 3.5 版本发生变更: 在 Linux 3.17 和更高版本上,现在使用 getrandom()
系统调用(如果可用)。在 OpenBSD 5.6 和更高版本上,现在使用 getentropy()
C 函数。这些函数避免了使用内部文件描述符。
在 3.5.2 版本发生变更: 在 Linux 上,如果 getrandom()
系统调用阻塞(urandom 熵池尚未初始化完毕),则退回一步读取 devurandom
。
在 3.6 版本发生变更: 在 Linux 上,getrandom()
现在以阻塞模式使用,以提高安全性。
在 3.11 版本发生变更: 在 Windows 上,将使用 BCryptGenRandom()
而不是已被弃用的 CryptGenRandom()
。
- os.GRND_NONBLOCK
- 默认情况下,从
devrandom
读取时,如果没有可用的随机字节,则getrandom()
会阻塞;从devurandom
读取时,如果熵池尚未初始化,则会阻塞。
如果设置了 GRND_NONBLOCK
标志,则这些情况下 getrandom()
不会阻塞,而是立即抛出 BlockingIOError
异常。
Added in version 3.6.
- os.GRND_RANDOM
- 如果设置了此标志位,那么将从
devrandom
池而不是devurandom
池中提取随机字节。
Added in version 3.6.