APUE 第八章 進程控制

1. 進程標識符

#include <unistd.h>
pid_t getpid(void);    //返回值:調用進程的進程ID
pit_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函數

現有進程調用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);
//返回值:若成功則返回流逝的牆上時鐘時間(單位:時鐘滴答數)若出錯則返回-1
struct 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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章