APUE 第八章 进程控制

来源:互联网 发布:淘宝优惠券短链接生成 编辑:程序博客网 时间:2024/05/17 01:11

1. 进程标识符

#include <unistd.h>pid_t getpid(void);    //返回值:调用进程的进程IDpit_t getppid(void);    //返回值:调用进程的父进程IDuid_t getuid(void);    //返回值:调用进程的实际用户IDuid_t geteuid(void);   //返回值:调用进程的有效用户IDgid_t getgid(void);    //返回值:调用进程的实际组IDgid_t getegid(void);   //返回值:调用进程的有效组ID

2.fork函数

现有进程调用fork创建新进程

#include <unistd.h>pid_t fork(void); 

由fork创建的新进程为child process。fork被调用一次,返回两次。child返回值是0,father返回值是新进程的进程ID。
fork使father返回值为child的进程ID的理由:一个进程有多个child,没有一个函数使进程可以获得其所有child的进程ID。
fork使child返回值0的理由:一个进程只有一个父进程,调用getppid可以获得father的进程ID,而且进程ID 0 为内核交换进程使用,child的ID不可能为0。
child 和father进程继续执行fork调用之后的指令

#include "apdu.h"int glob=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){        glob++;        var++;   }    else{        sleep(2);   }   printf("pid=%d,glob=%d,var=%d\n",getpid(),glob,var);   exit(0);}

wait 和 waitpid函数

  • 如果其所有子进程都还在运行,则阻塞。
  • 如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回。
  • 如果它没有任何子进程,则立即出错返回。
#include<sys/wait.h>pid_t wait(int *statloc);pid_t waitpid(pid_t pid, int *statloc, int options);//return: 进程ID of OK, 0, -1 on error

区别:

  • 在一个子进程终止前,wait使其调用者阻塞,而waitpid有一个选项,可使调用者不阻塞。
  • waitpid并不等待在其调用之后的第一个终止子进程,它有若干个选项,可以控制它所等待的进程。

waitpid的参数pid

  • pid==-1 等待任一子进程。
  • pid>0 等待其进程ID与pid相等的子进程。
  • pid==0 等待其组ID等于调用进程组ID的任一子进程。
  • pid<- 1 等待其组ID等于pid绝对值的任一子进程。

options参数(没看懂):

  • WCONTINUED 若实现支持作业控制,那么由pid指定的任一子进程在暂停后已经继续,但其状态尚未报告,则返回其状态
  • WNOHANG 若由pid指定的子进程并不是立即可用的,则waitpid不阻塞,此时其返回值为0
  • 若某实现支持作业控制,而由pid指定的任一子进程已处于暂停状态,并且其状态自暂停以来还未报告过,则返回其状态。WIFSTOPPED宏确定返回值是否对应于一个暂停子进程

用户标识

获取登录名

#include<unistd.h>char *getlogin(void)

如果调用此函数的进程没有连接到用户登录时所用的终端,则本函数会失败。(守护进程)

进程调度

#include <unistd.h>int nice(int incr);//返回值:成功返回新的nice值NZERO;若出错返回-1

进程时间

墙上时钟时间(wall clock time),是进程运行的时间总量

#include<sys/times.h>clock_t times(struct tms *buf);//返回值:若成功则返回流逝的墙上时钟时间(单位:时钟滴答数)若出错则返回-1struct tms{   clock_t tms_utime; /*user CPU time*/   clock_t tms_stime; /*system CPU time*/   clock_t tms_cutime; /* user CPU time, terminated children*/   clock_t tms_cstime; /*system CPU time, terminated children*/};
#include"apue.h"#include<sys/times.h>static void pr_times(clock_t, struct tms *,struct tms*);static void do_cmd(char *);int main(int argc, char *argv[]){    int i;    setbuf(stdout, NULL);    for(i=1;i<argc;i++)        do_cmd(argv[i]);    exit(0);}static void do_cmd(char *cmd){    struct tms tmsstart, tmsend;    clock_t start, end;    int status;    printf("\ncommand:%s\n", cmd);    if((start = times(&tmsstart))==-1)        err_sys("times error");    if((status=system(cmd))<0)        err_sys("system() error");    if((end= times(&tmsend))==-1)        err_sys("times error");    pr_times(end-start,&tmsstart,&tmsend);    pr_exit(status);}static void pr_times(clock_t real, struct tms *tmsstart, struct tms *tmsend){    static long clktck = 0;    if(clktck == 0)        if((clktck = sysconf(_SC_CLK_TCK))<0)            err_sys("sysconf error");    printf("  real: %7.2f\n", real/(double) clktck);    printf("  user: %7.2f\n",        (tmsend->tms_utime - tmsstart->tms_utime)/(double)clktck);    printf("  sys:  %7.2f\n",        (tmsend->tms_stime - tmsstart->tms_stime)/(double)clktck);    printf("  child user:  %7.2f\n",        (tmsend->tms_cutime-tmsstart->tms_cutime)/(double)clktck);    printf("  child sys:   %7.2f\n",        (tmsend->tms_cstime-tmsstart->tms_cstime)/(double)clktck);}