1. 进程标识符
pid_t getpid(void); //返回调用进程的进程ID
pid_t getppid(void); //返回调用进程的父进程ID
uid_t getuid(void); //返回调用进程的实际用户ID
uid_t geteuid(void); //返回调用进程的有效用户ID
gid_t getgid(void); //返回进程的实际组ID
gid_t getegid(void); //返回进程的有效组ID
2. fork函数
<span style="font-size:18px;">#include "apue.h"
int globvar = 6;
char buf[] = "a write to stdout\n";
int main(void)
{
int var;
pid_t pid;
var = 88;
if(write(STDOUT_FILENO, buf, sizeof(buf) - 1) != sizeof(buf) - 1)
err_sys("write error");
printf("before fork\n");
if((pid = fork()) < 0){
err_sys("fork error");
} else if(pid == 0) {
globvar ++;
var ++;
} else {
sleep(2);
}
printf("pid = %ld, glob = %d, var = %d\n", (long)getpid(), globvar, var);
exit(0);
}
/*****************
a write to stdout
before fork
pid = 40882, glob = 7, var = 89
pid = 40881, glob = 6, var = 88
*****************/
</span>
在子进程调用exec或exit之前,它会在父进程的空间中进行。它会保证子进程先进行,在它调用exec或exit之后,父进程才能被调度运行。
4. wait 和 waitpid
如果所有子进程都还在运行,则阻塞;如果一个子进程已终止,正等待父进程获取终止状态,则取得该子进程的终止状态立即返回;如果它没有任何子进程,则立即出错返回。
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int options); //pid和options对应不同的意义(P193)
#include "apue.h"
#include <sys/wait.h>
void pr_exit(int status)
{
if(WIFEXITED(status))
printf("normal termination, exit status = %d\n", WEXITSTATUS(status));
else if(WIFSIGNALED(status))
printf("abnormal termination, exit status = %d%s\n", WTERMSIG(status),
#ifdef WCOREDUMP
WCOREDUMP(status) ? " (core file generated)" : "");
#else
"");
#endif
else if(WIFSTOPPED(status))
printf("child stopped, signal number = %d\n", WSTOPSIG(status));
}
int main(void)
{
pid_t pid;
int status;
if((pid = fork()) < 0)
err_sys("fork error");
else if(pid == 0)
exit(7);
if(wait(&status) != pid)
err_sys("wait error");
pr_exit(status);
if((pid = fork()) < 0)
err_sys("fork error");
else if(pid == 0)
abort();
if(wait(&status) != pid)
err_sys("wait error");
pr_exit(status);
if((pid = fork()) < 0)
err_sys("fork error");
else if(pid == 0)
status /= 0;
if(wait(&status) != pid)
err_sys("wait error");
pr_exit(status);
}
/**************************************
rmal termination, exit status = 7
abnormal termination, exit status = 6
abnormal termination, exit status = 8
**************************************/
int waitid(idtype_t id, id_t id, siginfo_t, *infop, int options);
pid_t wait3(int *statloc, int options, struct rusage * rusage);
pid_t wait4(pid_t pid, int statloc, int options, struct rusage *rusage); //rusage里面含有终止进程及其所有子进程使用的资源概况
5. 竞争条件
#include "apue.h"
void charatatime(char *);
int main()
{
pid_t pid;
TELL_WAIT();
if((pid = fork()) < 0)
err_sys("fork error");
else if(pid == 0){
charatatime("output from child\n");
TELL_PARENT(getppid());
}
else{
WAIT_CHILD();
charatatime("output from parent\n");
}
exit(0);
}
void charatatime(char *ptr)
{
char *str;
int c;
setbuf(stdout, NULL);
for(str = ptr; (c = *str) != 0; str ++)
putc(c, stdout);
}
/********************
utput from child
output from parent
********************/
6. 函数exec(? P199)
7. 更改用户ID和更改组ID,解释器文件(P204-210)
8. system函数
#include "apue.h"
int main()
{
int status;
if((status = system("date")) < 0)
err_sys("system() error");
pr_exit(status);
if((status = system("nosuchcommand")) < 0)
err_sys("system() error");
pr_exit(status);
if((status = system("who; exit 44")) < 0)
err_sys("system() error");
pr_exit(status);
}
/******************************************
Fri Jul 8 00:41:33 PDT 2016
normal termination, exit status = 0
sh: nosuchcommand: command not found
normal termination, exit status = 127
lll :0 2016-07-07 23:19 (:0)
lll pts/13 2016-07-07 23:19 (:0)
normal termination, exit status = 44
******************************************/
8. 进程会计 (记录的顺序对应于进程终止的顺序)
9. 进程调度
int nice(int incr);
int getpriority(int which, id_t who);
//which 的参数有:PRIO_PROCESS(进程),PRIO_PGRP(进程组),PRIO_USER(用户ID)
int setpriority(int which, id_t who, int value);
#include "apue.h"
#include <errno.h>
#include <sys/time.h>
#if defined(MACOS)
#include <sys/syslimits.h>
#elif defined(SOLARIS)
#include <limits.h>
#elif defined(BSD)
#include <sys/param/h>
#endif
unsigned long long count;
struct timeval end;
void checktime(char *str)
{
struct timeval tv;
gettimeofday(&tv, NULL);
if(tv.tv_sec >= end.tv_sec && tv.tv_usec >= end.tv_usec){
printf("%s count = %lld\n", str, count);
exit(0);
}
}
int main(int argc, char *argv[])
{
pid_t pid;
char *s;
int nzero, ret;
int adj = 0;
setbuf(stdout, NULL);
#if defined(NZERO)
nzero = NZERO;
#elif defined(_SC_NZERO)
nzero = sysconf(_SC_NZERO);
#else
#error NZERO undefined
#endif
printf("NZERO = %d\n", nzero);
if(argc == 2)
adj = strtol(argv[1], NULL, 10);
gettimeofday(&end, NULL);
end.tv_sec += 10;
if((pid = fork()) < 0){
err_sys("fork error");
} else if(pid == 0) {
s = "child";
printf("current nice value in child is %d, adjusting by %d\n", nice(0)+nzero, adj);
errno = 0;
if((ret = nice(adj)) == -1 && errno != 0)
err_sys("child set scheduling priority");
printf("now child nice value is %d\n", nice(0) + nzero);
} else{
s = "parent";
printf("current nice in parent is %d\n", nice(0)+nzero);
}
for(;;){
if(++ count == 0)
err_quit("%s counter wrap", s);
checktime(s);
}
}
/************************************************
<< ./a.out
NZERO = 20
current nice in parent is 20
current nice value in child is 20, adjusting by 0
now child nice value is 20
parent count = 258526410
child count = 258645486
<< ./a.out 20
O = 20
current nice in parent is 20
current nice value in child is 20, adjusting by 20
now child nice value is 39
parent count = 507471598
child count = 7639840
************************************************/
clock_t times(struct tms *buf);