APUE函数笔记六: 进程控制

58 篇文章 0 订阅
49 篇文章 0 订阅

第八章  进程控制:

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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值