APUE函数笔记六: 进程控制

原创 2012年03月24日 15:19:02

第八章  进程控制:

#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
uid_t getuid(void);
uid_t geteuid(void);
gid_t getgid(void);
gid_t getegid(void);

#include <unistd.h>
pid_t fork(void);
   ret is -1 means error
   child process have a copy-data of parent process
pid_t vfork(void);
   ret is -1 means error
   child and parent share the data

#include <sys/wait.h>
pid_t wait(int * statloc);
pid_t waitpid(pid_t pid, int * statloc, int option);
     if statloc is NULL means we neednot child's exit-status
     ret is -1 means error
     pid:
         == -1, wait any child
         > 0,   wait child which child-gid == gid
         == 0,  wait any-child which child-group-id == parent-group-id
         < -1,  wait any-child which child-group-id == abs(pid)
     option:
         WCONTINUED, WNOHANG, WUNTRACED
     macros of check statloc:
         WIFEXITED(status)   --> WEXITSTATUS(status)
         WIFSIGNALED(status) --> WTERMSIG(status),  WCOREDUMP(status)
         WIFSTOPPED(status)  --> WSTOPSIG(status)
         WIFCONTINUED(status)

#include <sys/wait.h>    /* only surpport by Solaris */
int waitid(idtype_t idtype, id_t id, siginfo_t * infop, int options);
    ret is 0 means success, -1 means error

#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
pid_t wait3(int * statloc, int options, struct rusage * ru);
pid_t wait4(pid_t pid, int * statloc, int options, struct rusage * ru);
    ret is 0 means success, -1 means error

#include <unistd.h>
int execl(const char * pathname, const char * arg0, ... /* (char *)0 */);
int execv(const char * pathname, char * const argv[]);
int execle(const char * pathname, const char * arg0, ... 
           /* (char *)0, char * const envp[] */);
int execve(const char * pathname, char * const argv[], char * const envp[]);
int execlp(const char * filename, const char * arg0, ... /* (char *)0 */);
int execvp(const char * filename, char * const argv[]);
    if error, return -1; else no return

#include <unistd.h>
int setuid(uid_t uid);
int setgid(gid_t gid);
    if error return -1, else return 0

#include <unistd.h>
int setreuid(uid_t ruid, uid_t euid);
int setregid(gid_t rgid, gid_t egid);
    switch real id and effective id, if one of them is -1, means it not change
    if error return -1, else return 0

#include <unistd.h>
int seteuid(uid_t uid);
int setegid(gid_t gid);
    if error return -1, else return 0

#include <stdlib.h>
int system(const char * cmdstring);

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

#include <sys/times.h>
clock_t times(struct tms * buf);
    if error return -1, else return clock-tik
    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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int   globval = 6;
char  buf[] = "a write to stdout\n";

int 
main(void)
{
    int    locaval = 88;
    pid_t  pid;

    if (write(STDOUT_FILENO, buf, sizeof(buf)-1) != sizeof(buf)-1) {
        printf("write error\n");
        exit(-1);
    }
    fputs("before fork\n", stdout);

    if ((pid = fork()) < 0) {
        printf("fork error\n");
        exit(-1);
    }
    else if (pid == 0) {
        ++globval;
        ++locaval;
    }
    else {
        sleep(2);
    }

    printf("pid = %d, globval = %d, locaval = %d\n", 
           getpid(), globval, locaval);
    exit(0);
}

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int   globval = 6;
char  buf[] = "a write to stdout\n";

int 
main(void)
{
    int    locaval = 88;
    pid_t  pid;

    fputs("before vfork\n", stdout);

    if ((pid = vfork()) < 0) {
        printf("vfork error\n");
        exit(-1);
    }
    else if (pid == 0) {
        ++globval;
        ++locaval;
        _exit(0);
        /* if exit/return will fflush/drop the print, or close the stdout */
    }

    /* parent will wait and continue here */
    printf("pid = %d, globval = %d, locaval = %d\n", 
           getpid(), globval, locaval);
    exit(0);
}

#include <stdio.h>
#include <stdlib.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, signal number= %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));
    }
    else if (WIFCONTINUED(status)) {
        printf("child continued\n");
    }
    else {
        printf("*** unknown status ***\n");
    }
}

int 
main(void)
{
    pid_t pid;
    int   status;

    if ((pid = fork()) < 0) {
        printf("fork error\n");
        exit(-1);
    }
    else if (pid == 0) {
        exit(6);
    }

    if (wait(&status) != pid) {
        printf("wait error\n");
        exit(-1);
    }
    pr_exit(status);

    if ((pid = fork()) < 0) {
        printf("fork error\n");
        exit(-1);
    }
    else if (pid == 0) {
        abort();
    }

    if (wait(&status) != pid) {
        printf("wait error\n");
        exit(-1);
    }
    pr_exit(status);

    if ((pid = fork()) < 0) {
        printf("fork error\n");
        exit(-1);
    }
    else if (pid == 0) {
        status /= 0;
    }

    if (wait(&status) != pid) {
        printf("wait error\n");
        exit(-1);
    }
    pr_exit(status);

    exit(0);
}

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

int 
main(void)
{
    pid_t  pid;

    if ((pid = fork()) < 0) {
        printf("fork error\n");
        exit(-1);
    }
    else if (pid == 0) {
        if ((pid = fork()) < 0) {
            printf("fork error\n");
            exit(-1);
        }
        else if (pid > 0) {
            exit(0);
        }

        /*
         * We're the second child; our parent becomes init as soon
         * as our real parent calls exit(0) in the statement above.
         * Here's where we'd continue executing, knowing that when
         * we're done, init will reap our status.
         */
        sleep(2);
        printf("second child, parent pid = %d\n", getppid());
        exit(0);
    }

    if (waitpid(pid, NULL, 0) != pid) {
        printf("waitpid error\n");
        exit(-1);
    }

    /*
     * We're the parent (the original process); we continue executing,
     * knowing that we're not the parent of the second child.
     */
    exit(0);
}

#include <stdio.h>

int 
main(int argc, char * argv[])
{
    int            i;
    char        ** ptr;
    extern char ** environ;

    for (i = 0; i < argc; ++i) {
        printf("argv[%d]: %s\n", i, argv[i]);
    }

    for (i = 0, ptr = environ; *ptr != NULL; ++ptr, ++i) {
        printf("envp[%d]: %s\n", i, *ptr);
    }

    return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

char * env_init[] = { "USER=unknown", "PATH=/tmp", NULL };

int 
main(void)
{
    pid_t pid;

    if ((pid = fork()) < 0) {
        printf("fork error\n");
        exit(-1);
    }
    else if (pid == 0) {
        if (execle("./8-5.out", "8-5.out", "myarg1", 
            "MY ARG2", (char *)0, env_init) < 0) {
            printf("execle error\n");
        }
    }

    if (waitpid(pid, NULL, 0) != pid) {
        printf("waitpid error\n");
        exit(-1);
    }

    if ((pid = fork()) < 0) {
        printf("fork error\n");
        exit(-1);
    }
    else if (pid == 0) {
        if (execlp("8-5.out", "8-5.out", "only one arg", NULL) < 0) {
            printf("execle error\n");
        }
    }

    if (waitpid(pid, NULL, 0) != pid) {
        printf("waitpid error\n");
        exit(-1);
    }

    exit(0);
}

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>

int 
my_system(const char * cmdstring) /*version without signal handling */
{
    pid_t   pid;
    int     status;

    if (cmdstring == NULL) {
        return 1; /* always a command processor with UNIX */
    }

    if ((pid = fork()) < 0) {
        status = -1;
    }
    else if (pid == 0) {
        execl("bin/sh", "sh", "-c", cmdstring, NULL);
        _exit(127); /* execl error */
    }
    else {
        while (waitpid(pid, &status, 0) < 0) {
            if (errno != EINTR) {
                status = -1; /* error other than EINTR from waitpid */
                break;
            }
        }
    }

    return status;
}

int 
main(void)
{
    int status;

    status = my_system("./8-5.out");
    printf("system(./8-5.out): failed - %d\n", status);

    status = my_system("sleep 5");
    printf("system(sleep 5): failed - %d\n", status);

    status = my_system("date");
    printf("system(date): failed - %d\n", status);

    return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/times.h>

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) {
            printf("sysconf error\n");
            exit(-1);
        }
        else if (clktck == 0) {
            printf("clktck error\n");
            exit(-1);
        }
    }

    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);
}

void 
pr_exit(int status)
{
    if (WIFEXITED(status)) {
        printf("normal termination, exit status = %d\n", WEXITSTATUS(status));
    }
    else if (WIFSIGNALED(status)) {
        printf("abnormal termination, signal number= %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));
    }
    else if (WIFCONTINUED(status)) {
        printf("child continued\n");
    }
    else {
        printf("*** unknown status ***\n");
    }
}

void 
do_cmd(char * cmd)
{
    struct tms tmsstart;
    struct tms tmsend;
    clock_t    start;
    clock_t    end;
    int        status;

    printf("\ncommand: %s\n", cmd);

    if ((start = times(&tmsstart)) == -1) {
        printf("times error\n");
        exit(-1);
    }

    if ((status = system(cmd)) < 0) {
        printf("system error\n");
        exit(-1);
    }

    if ((end = times(&tmsend)) == -1) {
        printf("times error\n");
        exit(-1);
    }

    pr_times(end - start, &tmsstart, &tmsend);
    pr_exit(status);
}

int 
main(int argc, char * argv[])
{
    int i;

    setbuf(stdout, NULL); /* set stdout to unbuffered */
    for (i = 1; i < argc; ++i) {
        do_cmd(argv[i]);
    }
    exit(0);
}

#include <stdio.h>
#include <stdlib.h>

#ifdef SOLARIS
#define PSCMD    "ps -a -o pid,ppid,s,tty,comm"
#else
#define PSCMD    "ps -o pid,ppid,state,tty,command"
#endif

int 
main(void)
{
    pid_t pid;

    if ((pid = fork()) < 0) {
        printf("fork error\n");
        exit(-1);
    }
    else if (pid == 0) {
        exit(0);
    }

    sleep(4);
    system(PSCMD);

    exit(0);
}



相关文章推荐

APUE笔记---第八章 进程控制(函数fork、exit、wait等)

APUE笔记—第八章 进程控制1. 进程标识 每一个进程都有一个非负整数作为唯一进程ID。所以应用程序有时把进程ID作为名字的一部分来创建一个唯一的文件名。 虽然进程是唯一的,但是进程ID是可复用的。...
  • men_wen
  • men_wen
  • 2016年11月10日 22:48
  • 412

APUE函数笔记十一: 守护进程

第十三章  守护进程: #include void openlog(const char * ident, int option, int facility); void syslog(int...

APUE函数笔记十五: 高级进程间通信(部分)

第十七章  高级进程间通信(部分): #include int fattach(int filedes, const char * path); if success return 0, ...

APUE函数笔记七: 进程关系

第九章  进程关系: #include pid_t getpgrp(void); get pgid (>0) #include pid_t getpgid(pid_t pid); ...

APUE函数笔记五: 进程环境

第七章  进程环境: #include void exit(int status); void _Exit(int status); #include void _exit(int statu...

APUE函数笔记十三: 进程间通信

第十五章  进程间通信: #include int pipe(int filedes[2]); if success return 0, else error return -1 #in...

《APUE》笔记-第八章-进程控制

1.重点 fork、vfork、wait、waitpid、exec、exit,此外还介绍了:孤儿进程、僵尸进程、设置进程相关ID、system函数、进程会计、用户标识、进程调度、进程时间 2.进程标识...

【APUE 学习笔记】4: Unix Process Control 进程控制

本文是APUE第8章:进程控制知识点的总结和代码实践的总结。
  • elloop
  • elloop
  • 2016年10月11日 23:27
  • 274

APUE阅读笔记(八)——进程控制

说明:1、为什么写的第一篇阅读笔记就是八呢?因为之前看apue并没有写读书笔记,一直看到第八章,也就是标题中的这一章,才发现,不写是不行的,因为当我自己大量的接受新知识的时候,会遗忘的很厉害,也就是传...
  • sium__
  • sium__
  • 2016年04月18日 12:59
  • 268

《APUE》读书笔记—进程控制

本章介绍Unix的进程控制,包括进程创建,执行程序和进程终止,进程的属性,exec函数系列,system函数,进程会计机制。 1、进程标识符   每一个进程都有一个非负整数标识的唯一进程ID。ID...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:APUE函数笔记六: 进程控制
举报原因:
原因补充:

(最多只允许输入30个字)