SylixOS 进程 API

更新时间:
2024-03-14
下载文档

SylixOS 进程 API

在 POSIX 标准兼容进程 API 之外,SylixOS 也提供了符合 UNIX 标准的进程操作函数。在编写程序时推荐使用 POSIX 标准进程 API,但是在部分情况下使用该部分函数更为方便。

SylixOS 进程创建 API

spawn 函数与 exec 函数的区别是:exec 系列函数不会新建进程,只能在现有进程环境执行新的可执行文件。spawn 系列函数可以选择在现有进程环境执行可执行文件,也可以选择新建子进程。

#include <process.h>
int spawnl(int mode, const char *path, const char *argv0, ...);
int spawnle(int mode, const char *path, const char *argv0, ...);
int spawnlp(int mode, const char *file, const char *argv0, ...);
int spawnv(int mode, const char *path, char * const *argv);
int spawnve(int mode, const char *path, char * const *argv, char * const *envp);
int spawnvp(int mode, const char *file, char * const *argv);
int spawnvpe(int mode, const char *file, char * const *argv, char * const *envp);

以上函数原型分析:

  • 函数成功返回 0,失败返回-1 并设置错误码。
  • 参数 mode 是进程创建模式,其值如下表所示。
宏名解释
P_WAIT新建子进程,调用线程等待子进程退出再继续执行
P_NOWAIT新建子进程,调用线程不等待子进程退出
P_OVERLAY不新建子进程,在当前进程空间执行新程序
  • 参数 path 是可执行文件路径。
  • 参数 argv0 是第一个命令行参数,一般情况下第一个命令行参数为命令名称。
  • 参数 file 是可执行文件名,与参数 path 的区别是不带目录,应用程序加载器在指定路径搜索该文件。SylixOS 中应用程序动态库的搜索路径依次如下:
    • Shell 当前目录,注意不是应用程序所在目录;
    • PATH 环境中包含的搜索路径。
  • 参数 ... 为可变参数,表示命令行中剩余的参数,命令行参数以 0 结束。在 execle 函数中,在以 0 结束的命令行参数后还有一个环境变量数组,数组以 0 结束,见 envp 参数说明。
  • 参数 argv 是由命令行参数组成的字符串数组,数组以可执行文件名开始,以 0 结束。
  • 参数 envp 是需要预先设置的进程环境变量字符串集合,数组以 0 结束。

下面实例展示了如何使用 spawn 系列函数创建新进程并执行可执行程序。

#include <stdio.h>
#include <process.h>
int main (int argc, char *argv[])
{
    char *cmd[] = { "child_process", "spawnve demo", (char *)0 };
    char *env[] = { "PARENT=spawnve_demo", (char *)0 };
    fprintf(stdout, "before spawnve\n");
    spawnve(P_WAIT, "./child_process", cmd, env);
    fprintf(stdout, "after spawnve\n");
    return (0);
}

在 SylixOS Shell 中执行程序:

# ./Function_spawn
before spawnve
child process, spawnve demo
environment variable PARENT = spawnve_demo
after spawnve

由实例可见,当 mode 不为 P_OVERLAY 时,spawn 函数新建子进程,父进程继续执行,所以 spawn 函数最后的打印语句有效。

SylixOS 进程控制 API

设置当前进程为守护进程

#include <unistd.h>
int daemon(int nochdir, int noclose);

函数 daemon 原型分析:

  • 此函数成功返回 0,失败返回-1 并设置错误码。
  • 参数 nochdir 表示是否切换进程当前工作目录到根目录“/”。0 表示切换,其他表示不切换。
  • 参数 noclose 表示是否重定向标准输入、标准输出、标准错误输出到“/dev/null”文件。0 表示重定向,其他表示不重定向。

下面实例展示了 deamon 函数的用法。

#include <stdio.h>
#include <unistd.h>
int main (int argc, char *argv[])
{
    fprintf(stdout, "before daemon\n");
    daemon(0, 0);
    fprintf(stdout, "after daemon\n");
    while (1) {
        sleep(1);
    }
    return (0);
}

在 SylixOS Shell 中执行程序:

# ./deamon_demo&
before daemon
#

从运行结果可以看出在调用函数 daemon 后,打印语句无效,使用 ps 命令查看程序的运行状态。

# ps
      NAME            FATHER      STAT  PID   GRP    MEMORY    UID   GID   USER
---------------- ---------------- ---- ----- ----- ---------- ----- ----- ------
kernel                <orphan>       R     0     0        8KB     0     0   root
Daemon_Process        <orphan>       R    64    64      232KB     0     0   root
total vprocess : 2

等待指定子进程状态改变

#include <wait.h>
pid_t wait3(int *stat_loc, int options, struct rusage *prusage);

函数 wait3 原型分析:

  • 如果由于子进程状态改变导致函数返回,则返回 0。如果 options 设置了 WNOHANG 位,且没有子进程状态发生改变,则不等待且返回 0。其他情况返回-1 并设置错误号。
  • 参数 stat_loc 是子进程退出码。
  • 参数 option 是功能选项,由位掩码组成,如下表所示掩码位。
  • 参数 prusage 是子进程的资源使用情况。
宏名解释
WNOHANG如果为 1,函数不等待,当没有子进程状态改变时直接返回
WUNTRACED如果为 2,当子进程进入停止态时返回,否则只有当进程退出时返回

等待指定子进程状态改变

#include <wait.h>
pid_t wait4(pid_t pid, int *stat_loc, int options, struct rusage *prusage);

函数 wait4 原型分析:

  • 如果由于子进程状态改变导致函数返回,则返回子进程 ID。如果 options 设置了 WNOHANG  位,且没有子进程状态发生改变,则不等待且返回 0。其他情况返回-1 并设置错误码。
  • 参数 pid 可以有以下几种情况:。
    • pid > 0:表示等待进程号为 pid 的进程;
    • pid == 0:表示等待与调用进程同组的进程;
    • pid < -1:表示等待进程组 ID 为 pid 绝对值的进程。
  • 参数 stat_loc 是子进程退出码。
  • 参数 option 是功能选项,由位掩码组成,掩码位,如下表所示。
  • 参数 prusage 是子进程的资源使用情况。
宏名解释
WNOHANG如果为 1,函数不等待,当没有子进程状态改变时直接返回
WUNTRACED如果为 2,当子进程进入停止态时返回,否则只有当进程退出时返回

下面实例展示了 wait4 函数的使用方法:

#include <stdio.h>
#include <unistd.h>
#include <spawn.h>
#include <wait.h>

int main (int argc, char *argv[])
{
    pid_t          pid;
    int            status;
    struct rusage  rusage;

    if (posix_spawnp(&pid, "./wait_demo_child", NULL, NULL, NULL, NULL) != 0) {    /* 启动进程              */
        fprintf(stderr, "create child process failed\n");
        return  (-1);
    }
    fprintf(stdout, "create child process %d\n", pid);
    setpgid(pid, 10);                                                             /* 设置进程组ID           */
    fprintf(stdout, "waiting for group id 10...\n");
    pid = wait4(-10, &status, 0, &rusage);                                       /* 等待子进程退出          */
    fprintf(stdout, "waitpid returned, child process: %d, status: %d\n"
            "utime: %dus, stime: %dus\n",pid, status,
            (int)(rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec),
            (int)(rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec));
    if (posix_spawnp(&pid, "./wait_demo_child", NULL, NULL, NULL, NULL) != 0) {   /* 启动进程              */
        printf("create child process failed\n");
        return  (-1);
    }
    fprintf(stdout, "create child process %d\n", pid);
    setpgid(pid, 11);                                                            /* 设置进程组ID           */
    fprintf(stdout, "waiting for group id 11...\n");
    pid = wait4(-10, &status, 0, &rusage);                                       /* 等待子进程退出          */
    fprintf(stdout, "waitpid returned, child process: %d, status: %d\n"
            "utime: %dus, stime: %dus\n",pid, status,
            (int)(rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec),
            (int)(rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec));

    return (0);
}

在 SylixOS Shell 中执行程序,可以看到当子进程组 ID 与父进程调用 wait4 函数所传 pid 参数绝对值不同时,wait4 函数不返回。

# ./Function_wait4
create child process 8
waiting for group id 10...
child process 8 exit
waitpid returned, child process: 8, status: 0
utime: 40000us, stime: 0us
create child process 9
waiting for group id 11...
child process 9 exit
文档内容是否对您有所帮助?
有帮助
没帮助