一、执行新程序
使用fork或vfork创建子进程以后,子进程调用exec函数来执行另外一个函数。
exec函数族
#include<unistd.h>
int execve(const char *path, char *const argv[], char *const envp[]);
int execv(const char *path, char *const envp[]);
int execle(const char *path, const char *arg, ...);
int execl(const char *path, const char *arg, ...);
int exevp(const char *file, char *const argv[]);
int execlp(const char *file, const char *arg, ...);
用来替换进程映像的程序
exec函数实现程序
先编译第一个程序,生成可执行文件:gcc -o processimage processimage.c
再编译第二个程序,gcc -o execve execve.c
运行结果
由结果可知,当调用新函数以后,原有的子进程的映像被替代,子进程永远不会执行到printf(“process never go to here\n”)。
二、等待进程结束
僵尸进程:百度
当子进程先于父进程退出时,如果父进程没有调用wait和waitpid函数,子进程就会进入僵死状态,成为僵尸状态。
#include<sys/types.h>
#include<sya/wait.h>
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int options);
1、wait
wait函数使父进程暂停执行,直到他的一个子进程结束为止。
该函数的返回值是终止运行的子进程的PID。
参数statloc所指向的变量存放子进程的退出码,即子进程的main函数返回的值或子进程中exit函数的参数。
2、waitpid
wairpid用于等待某个特定进程结束,参数pid要指明等待的子进程的PID。
实现代码
三、setuid和aetgid
setuid设置实际用户ID和有效用户ID;setgid用来设置实际组ID和有效组ID
#include<stdio.h>
#include<unistd.h>
int setuid(uid_t uid);
int setgid(gid_t gid);
setuid函数遵循以下规则(setgid函数类似)
a.若进程具有root权限,则函数将实际用户ID、有效用户ID设置为参数uid
b.若进程不具有root权限,但uid等于实际用户ID,则setuid只将有效用户ID设置为uid
c.若以上两个条件都不满足,则函数调用失败,返回-1。
四、改变进程的优先级
1、getpriority
#include<sys/resource.h>
int getpriority(int which, int who);
函数返回一组进程的优先级
which和who的意义
PRIO_PROCESS:一个特定的进程,此时who的取值为进程ID
PRIO_PGRP:一个进程组的所有进程,此时who的取值为进程组ID
PRIO_USER:一个用户拥有的所有进程,此时参数who取值为实际用户ID
2、setpriority
#include<sys/resource.h>
int setpriority(int which, int who, int prio);
函数返回指定进程的优先级,出错返回-1。
3、nice
#include<unistd.h>
int nice(int increment);
nice系统调用是getpriority和setpriority的一种组合形式,nice系统调用相当于:
int nice(int increment)
{
int oldpro = getpriority(PRIO_PROCESS, getpid());
return setpriority(PRIO_PROCESS, getpid(), oldpro+increment);
}