日期:2014-05-16 浏览次数:20940 次
当多个进程都企图对共享数据进行某种处理,而最后的结果又取决于进程运行的顺序,则我们认为这发生了竞争条件。
如果一个父进程希望等待一个子进程终止,则它必须调用一种wait函数。如果一个进程要等待其父进程终止,可使用下列形式循环
while(getppid()!= 1)
sleep(1);
这种形式的循环(成为轮询)的问题是它浪费了CPU时间。
为避免竞争条件和轮询,可以使用信号机制,也可以使用各种形式的进程间通信(IPC)。
当进程调用一种exec函数时,该进程执行的程序完全替换为新程序,而新程序则从其main函数开始执行。因为调用exec并不是创建进程,所以前后的进程ID并未改变。exec只是用一个全新的程序替换了当前进程的正文、数据、堆和栈。
有六种exec函数可供使用,他们常常被称为exec函数。
#include <unistd.h>
int execl(const char *path, const char*arg, ...);
int execlp(const char *file, const char*arg, ...);
int execle(const char *path, const char*arg,..., char * const envp[]);
int execv(const char *path, char *constargv[]);
int execvp(const char *file, char *constargv[]);
int execve(const char *filename, char*const argv[],char *const envp[]);
这6个函数中只有execve是内核的系统调用,另外5个只是库函数,他们最终都要调用该系统调用。
在执行exec前后,实际用户ID和实际中ID保持不变,而有效ID是否改变则取决于所执行程序文件的设置用户ID位和设置组ID位是否设置。如果新程序的设置用户ID位已设置,则有效用户ID编程程序文件所有者ID,否则有效用户ID不变。
#include <sys/types.h>
#include <unistd.h>
int setuid(uid_t uid);
int setgid(gid_t gid);
setuid函数可以设置实际用户ID、有效用户ID。
setgid函数可以设置实际组ID、有效组ID。
#include <sys/types.h>
#include <unistd.h>
int setreuid(uid_t ruid, uid_t euid);
int setregid(gid_t rgid, gid_t egid);
上面两个函数的功能是交换实际用户ID和有效用户ID,交换实际组ID和有效组ID。
#include <sys/types.h>
#include <unistd.h>
int seteuid(uid_t euid);
int setegid(gid_t egid);
上面两个函数值更改有效用户ID和有效组ID。
多数UNIX系统提供一个选项以进行进程会计处理。启动该选项后,每当进程结束时内核就写一个会计记录。电信的会计记录包含总量较小的二进制数据,一般包括命令名。所使用的CPU时间总量、用户ID和组ID。
下面这个函数用于启动和禁止进程会计
#include<unistd.h>
int acct(constchar *filename);
当度量一个进程的执行时间时,UNIX系统使用三个进程时间值:
时钟时间、用户CPU时间和系统CPU时间。
时钟时间又称为墙上时间:它是进程运行的时间总量,其值与系统中同时运行的进程数有关。
用户CPU时间:执行用户指令所用的时间。
系统CPU时间是为该进程执行内核程序锁经历的时间。
用户CPU时间和系统CPU时间之和常被称为CPU时间。
#include <sys/times.h>
clock_t times(struct tms *buf);
任一进程都可调用times函数以获得它自己及终止子进程的三个进程时间值。此函数填写由buf指向tms结构,该结构定义如下:
struct tms {
clock_t tms_utime; /* user time */
clock_t tms_stime; /* system time */
clock_t tms_cutime; /* user timeof children */
clock_t tms_cstime; /* systemtime of children */
};
此结构没有包含墙上时钟时间的任何测试值。作为替代,times函数返回墙上时钟时间作为其函数值。调用两次times,用后一次的返回值减去前一次的返回值,所得的差值就是墙上时钟时间。
#include <stdlib.h>
int system(const char *command);
system函数通过fork创建的子进程来用exec函数调用command,而父进程wait函数等待的这一过程,来执行命令command系统命令。