unix c编程:进程控制

进程ID

    pid_t getpid();     //进程ID
    pid_t getppid();    //父进程ID
    pid_t getuid();     //实际用户ID
    pid_t geteuid();    //有效用户ID
    pid_t getgid();     //实际组ID
    pid_t getegid();    //有效组ID

创建进程fork与vfork

pid_t fork( void); //若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,返回-1

一个现有进程可以调用fork函数创建一个子进程。fork函数被调用一次但返回两次。
两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。对于fork创建的子进程,它是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,父子进程间不共享这些存储空间

pid_t vfork( void); //若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,返回-1

vfork 保证子进程先运行,在调用exec 或exit 之前与父进程数据是共享的,在它调用exec 或exit 之后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁。

进程中止处理wait
wait与waitpid

int wait(int* statloc);
int waitpid(pid_t pid, int* statloc, int options);

1) 如果其所有子进程都还在运行,则阻塞;只要有一个进程终止,wait就会返回。
2) 如果一个子进程已经终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回;
3) 如果它没有任何子进程,则立即出错返回;
区别:
1. 在一个子进程终止前,wait使其调用者阻塞,而waitpid有一个选项,可使调用者不阻塞;
2. waitpid()并不等待在其调用之后的第一个终止的子进程,它有若干个选项,可以控制它所等待的进程.

statloc参数——标记中止的子进程的状态
1. WIFEXITED(status):若为正常终止子进程返回的状态,则为真。
2. WIFSIGNALED(status):若为异常终止子进程返回的状态,则为真(接到一个不捕捉的信号,如SIGCHLD)。
3. WIFSTOPPED(status):若为当前暂停的子进程的返回的状态,则为真。对于这种情况,可执行WSTOPSIG(status),取使子进程暂停的信号编号。
4. WIFCONTINUED(status):若在作业控制暂停后已经继续的子进程返回了状态,则为真.(POSIX.1的XSI扩展,仅用于waitpid)

关于waitpid参数分析:
pid的可能值为:
小于-1:意味着等待的子进程为pid的绝对值标识的进程组中的任意一个
等于-1:意味着等待其任意一个子进程
等于0:意味着等待和调用进程在同一个进程组中的任意子进程
大于0:意味着等待的子进程的进程id为指定值

options的值可以为如下三个值的或操作组合:
WNOHANG:设置该参数调用进程不会被阻塞,不论子进程状态有无改变,立即返回
WUNTRACED:设置该参数使得当子进程暂停时也会返回。
WCONTINUED:设置该参数后,当等待的子进程收到信号SIGCONT,由暂停变为运行状态后也会返回。
waitid()类似于waitpid,但是会更加详细的配置等待哪一个子进程的设置,以及返回的信息。

pid_t wait3 ( int *status, int option, struct rusage *ru );
pid_t wait4 ( pid_t pid, int *status, int option, struct rusage *ru );

wait3和wait4函数除了可以获取子进程状态转变信息外,还可以获得子进程的资源使用信息。

进程内任务调度exec
exec的几个标准函数使用

扫描二维码关注公众号,回复: 2742987 查看本文章
#include <unistd.h>
int execl(const char *path, const char *arg, ...)
int execv(const char *path, char *const argv[])
int execle(const char *path, const char *arg, ..., char *const envp[])
int execve(const char *path, char *const argv[], char *const envp[])
int execlp(const char *file, const char *arg, ...)
int execvp(const char *file, char *const argv[])

1) 当进程执行完成,希望执行下一个任务,就可以调用任何exec 函数族让自己重生。
2) 如果一个进程想执行另一个程序,那么它就可以调用fork函数新建一个进程,然后调用任何一个exec函数使子进程重生。
成功,函数不会返回; 出错,返回-1,失败原因记录在error中

进程用户ID与组ID设置

int setuid(uid_t uid); //成功返回0,如果失败返回-1,并将errno设置为合适的值
int setgid(gid_t gid); //成功返回0,如果失败返回-1,并将errno设置为合适的值

进程系统调用system
system函数——执行命令行操作

int system(const char * string); 

返回值 =-1:出现错误 =0:调用成功但是没有出现子进程 >0:成功退出的子进程的id
函数说明
system()会调用fork()产生子进程,由子进程来调用/bin/sh string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。
在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。
注意: 在编写具有SUID/SGID权限的程序时请勿使用system(),system()会继承环境变量,通过环境变量可能会造成系统安全的问题。

进程调度nice

int nice(int inc);

在Linux中,进程运行的优先级分为-20~19等40个级别,数值越小运行优先级越高。
函数nice是将当前进程运行的优先级增加指定值。当计算出来的值小于-20,则进程将以优先级-20运行;当计算出来的值大于19,则进程将以优先级19运行。若增加正值,则表示降低进程运行优先级;若增加负值,则表示升高进程运行优先级。但只有具有超级用户权限的用户才可以以负数作为函数的参数,否则该函数将返回错误。
注意:当函数返回-1时,不一定就是函数操作失败。因为若函数成功调整进程运行优先级后的优先级为-1,函数也返回-1,所以在判断函数是否操作失败时,除了判断函数返回的值是否为-1外,还需要查看 errno的值是否为相关错误码。

猜你喜欢

转载自blog.csdn.net/ly601579033/article/details/81002431