C 编程/POSIX 参考/spawn
Spawn 指的是一个加载并 执行 新的 子进程 的函数。 当前进程 可能会或可能不会继续异步执行。创建一个新的子进程需要足够的内存,以便子进程和当前程序都可以执行。
在 Microsoft Windows 操作系统系列中有一组 spawn 函数。 在 POSIX 标准 [1] 的可选扩展中也有一组不同的 spawn 函数。
不同的版本
[edit | edit source]Microsoft Windows 的 spawn 函数受到 Unix 函数 fork 和 exec 的启发;然而,由于 Windows 不支持 fork(至少在 Win32 API 中; POSIX 模拟环境,如 Cygwin 或 SFU 确实支持),spawn 函数作为 fork-exec 组合的替代品提供。然而,spawn 函数虽然能够充分处理最常见的用例,但它缺少 fork-exec 的全部功能,因为在 fork 之后,任何将在 exec 后保留的进程设置都可以更改。然而,在大多数情况下,可以通过使用更低级的 CreateProcess API 来弥补这种缺陷。
Posix spawn 函数的引入是为了在不支持交换或动态地址转换的嵌入式环境的 Posix 实现中支持进程 [2]。
Microsoft Windows spawn 函数
[edit | edit source]在 spawnl、spawnlp、spawnv 和 spawnvp 调用中,子进程继承父进程的环境。在进行 spawn 调用时,打开的文件将保留在子进程中。
原型
[edit | edit source]int spawnl(int mode, char *path, char *arg0, ...);
int spawnle(int mode, char *path, char *arg0, ..., char ** envp);
int spawnlp(int mode, char *path, char *arg0, ...);
int spawnlpe(int mode, char *path, char *arg0, ..., char ** envp);
int spawnv(int mode, char *path, char **argv);
int spawnve(int mode, char *path, char **argv, char ** envp);
int spawnvp(int mode, char *path, char **argv);
int spawnvpe(int mode, char *path, char **argv, char ** envp);
函数名称
[edit | edit source]每个函数的基名是 spawn,后面跟着一个或多个字母
名称 | 说明 |
---|---|
e | 明确地将一个指向环境参数的指针数组传递给子进程。 |
l | 命令行参数被单独传递给函数。 |
p | 使用 PATH 环境变量来查找要执行的文件。 |
v | 命令行参数作为指针数组传递给函数。 |
模式
[edit | edit source]mode 参数决定子进程运行的方式。mode 的值是
名称 | 说明 |
---|---|
P_OVERLAY | 用子进程覆盖父进程,这将销毁父进程。这与 exec* 函数的效果相同。 |
P_WAIT | 挂起父进程,直到子进程执行完毕(同步 spawn)。 |
P_NOWAIT, P_NOWAITO | 继续与新进程并发执行调用进程(异步 spawn)。 |
P_DETACH | 子进程在后台运行,没有访问控制台或键盘的权限。对新进程的 _cwait 调用将失败(异步 spawn) |
路径
[edit | edit source]path 参数指定要执行的程序的文件名。对于 spawnlp 和 spawnvp,如果文件名没有路径且不在当前目录中,则 PATH 环境变量 将决定要搜索文件的目录。argv[0] 指向的字符串是要运行的程序的名称。
传递给 spawned 程序的命令行由 spawn 调用中的字符字符串 arg0 到 argn 组成。这些字符串的接受的最大组合长度在不同的编译器之间有所不同,从 Digital Mars 上的 128 个字符 [3] 到 Microsoft Visual C++ 上的 1024 个字符 [4],或者在 DJGPP 上允许的尽可能多的内存 [5]。argn 之后的最后一个参数必须是 NULL 指针。
argv
[edit | edit source]argv 参数是一个字符指针数组。数组中的最后一个指针必须为空,以指示列表的结尾。
envp
[edit | edit source]spawnle、spawnlpe、spawnve 和 spawnvpe 调用允许用户通过在 envp 参数中传递环境设置列表来更改子进程的环境。此参数是一个字符指针数组;每个指针(最后一个指针除外)都指向一个空终止的字符串,定义了一个环境变量。环境变量具有以下形式
- name=value
其中 name 是变量名,value 是它的值。数组中的最后一个指针为空。当 envp 参数为空时,子进程继承父进程的环境设置。
spawn 函数可以在 Microsoft Windows 下使用。它们使用 LoadModule 运行 spawned 进程。如果失败,将尝试 spawn 一个普通的 MS-DOS 进程。如果 spawn 了一个 Windows 应用程序,则可以使用 exec_instancehandleget 获取实例句柄。可以使用 _exec_showset、_exec_showget 和 _exec_showreset 函数指定 spawned 程序的显示方式。
返回值
[edit | edit source]返回值表示 spawned 程序的退出状态。值为零表示 spawned 程序成功执行。正值表示 spawned 程序已执行,但被 中止 或以错误结束,返回的值是子进程的退出状态。负值表示 spawned 程序未执行,并且 errno 已设置。在 Microsoft Windows 下,spawn 返回从 LoadModule 返回的负数错误代码,以与 C 运行时库兼容。可能会遇到以下错误代码
值 | 说明 |
---|---|
-2 |
文件未找到 |
-3 |
路径未找到 |
-11 |
无效的 .exe 文件(对于 Windows) |
-13 |
DOS 4.0 应用程序 |
-14 |
未知的 .exe 类型(可能是 DOS 扩展) |