Unix进程控制

  wait函数和waitpid函数用于捕获子进程停止信号,获取子进程停止状态,并在子进程结束后清除该进程所占用的系统资源。其函数原型为

#include <sys/wait.h>

pid_t wait(int *statloc);                      //返回已结束子进程id或-1
pid_t waitpid(pid_t pid, int *statloc, int options);     //返回已结束子进程id、0或-1

  wait函数监听所有子进程,当存在任一子进程停止时,wait函数立即返回。waitpid函数监听子进程受pid参数限制,当pid>0时,pid值为指定子进程id;当pid值为0时,waitpid函数监听与父进程具有相同用户组的子进程;当pid值为-1时,waitpid函数监听所有子进程,与wait函数等价;当pid<-1时,waitpid函数监听所有用户组id与pid绝对值相等的子进程。参数statloc用于存储子进程返回状态(是否正常结束、是否异常结束、是否暂停、进程返回值),options用于指定waitpid函数何时返回。

  对子进程返回状态需要使用宏定义进行判断,如:

WIFEXITED(status);               //子进程正常结束时为真
WIFSIGNALED(status);         //子进程被异常终止时为真
WIFSTOPED(status);             //子进程被暂停时为真
WIFCONTINUED(status);     //子进程继续运行时为真

WEXITSTATUS(status);        //获取子进程正常结束时返回值
WTERMSIG(status);              //获取子进程异常终止信号
WCOREDUMP(status);        //获取子进程异常终止所产生的内核文件
WSTOPISG(ststus);               //获取引起子进程暂停的信号

   wait3与wait4函数与wait、waitpid函数类似。区别在于wait3、wait4可以读取子进程所占用的资源信息。结构体rusage中内容可通过查询man手册getrusage(2)获得。其函数原型为

pid_t wait3(int *statloc, int options, struct rusage *rusage);
pid_t wait4(pid_t pid, int *statloc, int options, struct rusage *rusage);

 

  exec系列函数用于在当前进程中执行指定程序。exec系列函数包括

#include <unistd.h>
int execl( const char *parhname, const char *arg0, ... /* (char*) 0 */ );
int execv( const char *pathname, char *const argv[]);
int execle( const char *pathname, const char *arg0, ... /* (char*) 0 */ , char *const envp[]);
int execve( const char *pathname, char *const argv[], char *const envp[]);

int execlp( const char *filename, const char *arg0, ... /* (char*) 0 */ );
int execvp(const char *filename, char *const argv[]);

 

在上述命名中,字母l代表可变参数列表(list),字母v代表向量数组(vector),字母e代表环境参数(environment),字母p代表使用PATH环境路径搜索文件。

  exec系列函数的区别在于

  1. execl、execv、execle、execve函数中第一个参数为可执行文件的绝对路径。execlp、execvp函数中第一个参数为可执行文件的文件名。当filename参数为文件名时,可执行文件搜索顺序为PATH环境变量中值的顺序。
  2. 当execlp与execvp函数无法找到可机械执行文件时,filename参数将被理解为shell脚本命令,由/bin/sh负责执行该命令。
  3. 在具有可变参数列表的exec函数(execl、execle、execlp)中,可变参数最后一个参数必须为NULL,代表可变参数结束。可变参数从第0个参数开始。
  4. execle、execve函数中可指定完整的环境参数列表。其他几个exec函数将复制父进程的环境参数列表。

  在大多数Unix系统中,exec系列函数仅有一个系统函数,其他几个函数可通过对系统函数的加工来实现,其调用关系如图1所示

图1. exec系列函数调用关系

 

  使用exec函数执行的程序将从调用进程继承

  • 进程ID和父进程ID
  • 实际用户ID和实际用户组ID
  • 附加用户组ID
  • 进程组ID
  • 会话ID
  • 控制终端
  • 警报(alarm clock)剩余时间
  • 当前工作目录
  • 根目录
  • 文件权限掩码(file mode creation mask)
  • 文件锁
  • 进程信号掩码
  • 未处理信号
  • 资源限制
  • 用户CPU时间(tms_utime)、系统CPU时间(tms_stime)、用户终止子进程时间(tms_cutime)、系统终止子进程时间(tms_cstime)

当调用进程中已打开的文件执行时关闭标识符(close-on-exec flag)被设置,exec函数执行时,文件被关闭。

 

  setuid、seteuid、setreuid函数可用于修改当前进程的真实用户id与有效用户id。其原型为

#include <unistd.h>
int setuid( uid_t uid);
int seteuid( uid_t uid);
int setreuid(uid_t ruid, uid_t euid);

 

  其修改关系如图2所示

图2. setuid、seteuid、setreuid修改关系图

  在进程开始运行时,保留设置用户ID(saved set-user-ID)从有效用户id复制而来。用户无法直接获取保留设置用户id的值(仅能够通过获取有效用户id来获得相同值)。

  当使用setuid,且当前进程不具有超级用户权限时,如果uid与真实用户id或保留设置用户id相同,则有效用户id被修改为uid的值。若当前进程具有超级用户权限,三种用户id(真实用户id、有效用户id、保存设置用户id)都将被修改。

  当使用setreuid时,且无超级用户权限时,其参数必须与有效用户id或真实用户id相同。若不想对某一用户id做出修改,可将参数设置为-1。

  

posted @ 2012-08-10 17:19  o0慢节奏0o  阅读(733)  评论(0编辑  收藏  举报