函数:
pid_t fork(void);
pid_t vfork(void);
头文件:unistd.h
作用:都是创建一个与当前进程相同的新进程。
区别:
fork函数:该函数产生的的新进程是父进程的一个拷贝,但是该进程同父进程使用不同的数据段和堆栈段;fork调用将执行2次返回,一次是父进程的返回,一次是子进程的返回。从父进程返回的是子进程的PID,对子进程而言,如果正确返回则返回的是0,错误时返回为-1,并且将errno设置为相应值。对子进程和父进程而言,他们在返回之后都将执行fork之后的语句。 此外,父进程和子进程彼此运行无关,因此他们的返回次序无法确定。
vfork函数:与fork的区别有两点,一是它不完全复制父进程的数据段,而是与父进程共享数据段,二是它对父子进程的执行顺序有所限制,当调用vfork后,父进程被挂起,子进程运行完exec函数族或调用exit时才解除父进程的挂起状态;
Exec函数簇:
int execl(const char *pathname,const char *arg, …);
int execlp(const char *filename,const char *arg,…);
int execle(const char *pathname,const char *arg,…,char *const envy []);
int execv(const char *pathname,char *const argv[]);
int execvp(const char *filename, char *const argv[]);
int execve(const char *pathname,char *const argv[],char *const envp[]);
头文件:unistd.h
函数差异:
前3个函数都是以execl开头的与后3个都是以execv开头的区别在于execv开头的函数是以"char *argv[]"这样的形式传递命令行参数,而execl开头的函数是把参数一个一个列出来,然后以一个NULL表示结束。
execle和execve使用了char *envp[]传递环境变量,且会用指定的环境变量去替代默认的环境变量。其它的4个函数将把默认的环境变量不做任何修改地传给被执行的应用程序。
2个以p结尾的函数execlp和execvp,的第1个参数file可以简单到仅仅是一个文件名,这两个函数可以自动到环境变量PATH制定的目录里去寻找该文件。
函数:
int __clone(int (*fn)(void *arg),void *child_stack,int flag,void *arg);
参数说明:
fn是函数指针,指向要执行的函数,参数child_stack是子进程堆栈段的指针参数flags是用于表示不同继承关系内容的标识,参数arg是指向存放要传递所调用程序的参数的缓冲区。
flag标识 |
含义 |
CLONE_VM |
继承父进程的虚拟存储器 |
CLONE_FS |
集成父进程的chroot(根目录)、chdir(当前目录)和umask(权限掩码) |
CLONE_FILES |
继承父进程的文件描述符 |
CLONE_PID |
继承父进程的文件锁、进程号及时间片 |
CLONE_SIGHAND |
继承父进程的信号处理程序 |
函数(1):
pid_t wait(int *status);
pid _t waitpid(pid_t pid, int *status, int options);
头文件: sys/types.h sys/wait.h
作用:wait等待子进程,waitpid可以等待指定的子进程;
函数 (2):
pid_t wait3(int *status,int options,struct rusage *rusage);
pid _t wait4(pid_t pid,int *status,int options,stuct rusage *rusage);
头文件:sys/types.h sys/resource.h sys/wait.h
作用:
wait3相当于wait函数,wait4相当于waitpid函数,其参数rusage为一结构指针,调用这两个函数时,如果rusage不为NULL时,则关于子进程执行时的相关信息将写入该指针指向的缓存区内。
函数(1):
void exit(int status);
int atexit(void (*function)(void));
int on_exit(void(*function)(int ,void),void *arg);
void abort(void);
头文件: stdlib.h
函数(2):void _exit(int status); 头文件:unistd.h
函数(3): void assert(int expression); 头文件:assert.h
exit函数是标准c中提供的函数,它用来终止正在运行的程序,将关闭所有被进程打开的文件描述符;
atexit函数用于注册一个不带参数也没有返回值的函数,以供程序正常退出时调用。参数function为所所指向程序的函数指针。调用成功调用返回0,调用失败返回-1,并将errno设置为相应值;
on_exit函数与atexit类似,但其注册的函数有参数;
abort函数用来发送一个SIGABRY信号,该信号将使当前进程终止;
_exit函数用来结束进程,与exit函数的不同在于,调用_exit函数可以关闭一些linux下的一些特有的句柄;
assert是一个宏,它讲先计算expression的值,如果值为0,则调用abort函数结束进程。通常使用此函数来检测某些参数是否有不当情况出现,并在不当情况发生时以结束进程作为相应的处理。
属性 |
具体含义 |
实际用户标识符 |
调用该进程的用户标识符 |
有效用户标识符 |
进程目前运行的用户标识符 |
文件系统用户标识符 |
用于检测进程对文件系统访问的权限,在通常情况下等于有效用户标识符 |
保存的用户标识符 |
当进程第一次调用某个程序时设置的最初的有效用户标识符 |
实际的组标识符 |
调用进程的用户主要所在组的组标识符 |
有效的组标识符 |
进程目前运行的用户主要所在组的组标识符 |
文件系统的组标识符 |
用于检测用户主要组队文件系统访问的权限,在通常情况下等于有效用户组标识符 |
保存的组标识符 |
当进程第一次调用某个程序时设置的最初的有效组标识符 |
附加的组列表 |
用户所属组的列表 |
函数:
uid_t getuid(void); //获取实际用户标识符
gid_t getgid(void);//获取实际组标识符
uid_t geteuid(void);//获取有效用户标识符
gid_t getegid(void);//获取有效组标识符
头文件: unistd.h sys/types.h
函数:
int setuid(uid_t uid);
int setgid(gid_t gid);
int seteuid(uid_t euid);
int setegid(gid_t egid);
int setreuid(uid_t ruid,uid_t euid);
int setregid(gid_t rgid,gid_t egid);
int setfsuid(uid_t fsuid);
int setfgid(gid_t fguid);
头文件:unistd.h sys/types.h
相关说明:
函数 |
由普通用户调用 |
有超级用户调用 |
||
参数所选值 |
相应改动 |
参数所选值 |
相应改动 |
|
setuid |
实际用户ID 有效用户ID 保存用户ID |
有效用户ID 文件系统用户ID |
均可 |
实际用户ID 有效用户ID 文件系统用户ID 保存的用户ID |
setgid |
实际组ID 有效组ID |
有效组ID 文件系统组ID |
均可 |
实际组ID 有效组ID 文件系统组ID 保存的组ID |
seteuid |
实际用户ID 有效用户ID |
有效用户ID 文件系统用户ID |
均可 |
有效用户ID 文件系统用户ID |
setegid |
实际组ID 有效组ID 保存的组ID |
有效组ID 文件系统组ID |
均可 |
实际组ID 文件系统组ID |
setreuid |
ruid:真实用户ID egid:有效用户ID |
交换进程真实用户ID和有效用户ID |
ruid:真实用户ID egid:有效用户ID |
交换进程真实用户ID和有效用户ID |
setfregid |
ruid:真实用户ID egid:有效用户ID |
交换进程真实组ID和有效组ID |
ruid:真实用户ID egid:有效用户ID |
交换进程真实组ID和有效组ID |
setfsuid |
实际用户ID 有效用户ID 文件系统用户ID 保存用户的ID |
文件系统用户ID |
实际用户ID 有效用户ID 保存的用户ID |
文件系统的用户ID |
setfsgid |
实际组ID 有效值ID 文件系统组ID 保存的组ID |
文件系统的组ID |
实际组ID 有效值ID 文件系统组ID 保存的组ID |
文件系统的组ID |
函数:int system(const char *cmdstring); 头文件:stdlib.h
相关说明:
如当参数cmdstring设为NULL,则调用system函数可以用于测试system函数是否有效,调用成功时,返回非NULL指针,表示system函数有效,调用失败时,返回0,表示system函数无效。通常在linux系统中system有效
函数(1):pid_t getpgrp(void); 头文件:sys/types.h unistd.h
作用:返回调用它的进程的进程组号;进程组的各个进程中,有一个特别的进程leader,他的进程ID和进程组ID一致,且leader进程可以创建一个进程组,也可以创建属于该进程组的进程。
函数(2):int setpgid(pid_t pid, pid_t pgid);
作用:创建一个新的进程组或将一个进程加入到一个已存在的进程组中,当pid和pgid相同时,用于创建一个新的进程组,,当pgid是一个已经存在的进程组ID时,将pid代表的进程加入到该进程组中。调用成功时,返回0,失败时,返回-1。
l 调度策略和参数
Linux系统中处理多进程的方式为抢占式的,即一个进程使用CPU直至系统抢占CPU给另一个进程使用,不同的调度策略和不同的参数设置,对应于不同的时间片使用CPU的方式。
函数:
Int sched_setscheduler(pid_t pid,int policy,const structsched_param *param);
Int sched_getscheduler(pid_t pid);
头文件:sched.h
作用:sched_setscheduler 用于设定进程调度策略和参数,sched_getscheduler用于获取进程调度策略和参数,函数sched_setscheduler 中,para结构用于保存进程的调度参数,policy表示调度策略,具体取值如下:
SCHED_OTHER:默认的调度策略,按通常的方法啊分配时间片;
SCHED_FIFO:对应于先进先出规则,实时分配时间片。可以抢占使用SCHED_OTHER的进程,使用SCHED_FIFO的进程只能被优先级比它高的进程抢占;
SCHED_RR:轮换规则,实时分配时间片。也可以抢占使用SCHER_OTHER的进程。使用SCHED_RR的进程在需要与其它进程分享时间片时可以被相同优先级的进程抢占,但errno将被设置为相应值;
l 优先级的设定
系统对不同进程所分配的CPU时间的多少主要是由进程的优先级决定的。每一个进程都有自己的优先级。静态优先级高的会抢占静态优先级低的。对静态优先级为0的进程将依照其动态优先级来分配运行时间,优先级的值越小,优先级越高,对进程执行一定操作可以改变进程动态优先级,linux系统中,进程的优先级不是一成不变的。
函数(1):int nice(int inc);
头文件:unistd.h
作用:改变进程的动态优先级,调用该函数的进程的优先级将加上inc所设定的值,只有超级用户进程调用nice时,才可以将inc的值设定为负值,调用成功返回0,调用失败返回-1,并将errno设定为相应值。
函数(2):
setpriority(int which, int who, int prio);
getpriority(int which,int who);
头文件:sys/time.h sys/resource.h
作用:setpriority用于设定进程,进程组或用户的动态优先级,who表示要设定优先级的进程,prio用于指定进程优先级(-20到20之间),which表示所操作的对象,具体如下
which取值 |
含义 |
PRIO_PROCESS |
设置进程的动态优先级 |
PRIO_PGRP |
设置进程组的动态优先级 |
PRIO_USER |
设置用户的动态优先级 |
备注:调用getpriority函数时,其返回值为进程的优先级。一个进程的优先级可能为-1。因此调用getpriority时,如果返回为-1时,并不表示函数的调用失败,而需要根据errno值来确定,因此,调用getpriority函数前,应该先将errno清楚,调用完毕后检测errno的值来确定调用是否成功。
函数(3):
Int sched_get_priority_max(int policy);
Int sched_get_priority_min(int policy);
头文件:sched.h
作用:sched_get_priority_max和sched_get_priority_min分别用于获取由参数policy指定的调度策略下优先级的最大值和最小值。