zoukankan      html  css  js  c++  java
  • AUPE学习第八章------进程控制

    每个进程都有一个非负整形表示的唯一进程ID。

    init进程是一号进程,是第一个用户态的进程。它负责内核启动以后启动一个unix系统,

    它读取的配置文件一般在/etc/rc*、/etc/inittab、/etc/init.d中。

    下面的函数返回进程的一些标识:

    pid_t   getpid(void)   //调用进程的进程ID.

    pid_t   getppid(void)   //调用进程的父进程。

    uid_t   getuid(void)   //返回调用进程的实际用户ID。

    uid_t   geteuid(void)   //返回用户的有效用户id

    uid_t   getgid(void)      //调用进程的实际用户组ID。

    gid_t    getegid(void)     //调用进程的实际组ID。

    8.3fork函数

    一个进程可以调用fork来创建新的进程。
    pid_t    fork(void)
    #include "apue.h"
    
    int glob = 6;
    char buf[] = "a write to stdout
    ";
    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
    ");
            if ((pid = fork()) < 0)
            {
                    err_sys("fork error");
            }else if (pid == 0)
            {
                    glob++;
                    var++;
            }else
            {sleep(2);
            }
            printf("pid = %d, glob = %d, var = %d
    ", getpid(), glob, var);
            exit(0);
    }
    运行结果:
    [root@localhost apue]# ./a.out 
    a write to stdout
    before fork
    pid = 7656, glob = 7, var = 89
    pid = 7655, glob = 6, var = 88
    [root@localhost apue]# ./a.out >fort.out
    [root@localhost apue]# cat fort.out 
    a write to stdout
    before fork
    pid = 7671, glob = 7, var = 89
    before fork
    pid = 7670, glob = 6, var = 88
    

    
    
    父进程和子进程共享打开的文件。子进程把父进程的所有打开的文件描述符都复制到子进程中。
    
    
    子进程和父进程共享一个文件表项。

    8.4vfork函数

    vfork函数的调用序列和返回值与fork相同。但两个语义不同。
    vfork可以保证子进程的先与父进程执行。它调用exec或者exit之后父进程才可能被调度执行。
    vforktest.c:
    #include "apue.h"
    int glob = 6;
    int main()
    {
            int var;
            pid_t pid;
            var = 88;
            printf("before vfork
    ");
            if ((pid = vfork()) < 0){
                    err_sys("vfork error");
            }else if (pid == 0){
                    glob++;
                    var++;
                    _exit(0);
            }
            printf("pid = %d, glob = %d, var = %d
    ", getpid, glob, var);
            exit(0);
    }
    运行结果:
    [root@localhost apue]# vim vforktest.c
    [root@localhost apue]# gcc vforktest.c 
    [root@localhost apue]# ./a.out 
    before vfork
    pid = 134513812, glob = 7, var = 89

    8.6wait和waitpid函数

    当一个进程正常或者异常终止时,内核就向其父进程发送SIGCHLD信号。
    父进程可以忽略这个信号或者调用一个执行的函数。系统默认是忽略它。
    pid_t   wait(int  *statloc)
    pid_t   waitpid( pid_t   pid,  int   *statloc,   int   options)
    若成功返回进程ID,出错则返回-1。
    下面为关于子进程退出状态的操作.
    exittest.c:
    #include "apue.h"
    #include <sys/wait.h>
    
    void pr_exit(int status);
    int main(void)
    {
            pid_t pid;
            int status;
            if ((pid = fork()) < 0)
                    err_sys("error fork");
            else if (pid == 0)
                    exit(7);
            if (wait(&status) != pid)
                    err_sys("wait error");
            pr_exit(status);
    
            if ((pid = fork()) < 0)
                    err_sys("error fork");
            else if (pid == 0)
                    abort();
            if (wait(&status) != pid)
                    err_sys("wait error");
            pr_exit(status);
    
            if ((pid = fork()) < 0)
                    err_sys("error fork");
            else if (pid == 0)
                    status /= 0;
            if (wait(&status) != pid)
                    err_sys("wait error");
            pr_exit(status);
    
            exit(0);
    }
    
    void pr_exit(int status)
    {
            if (WIFEXITED(status))
                    printf("normal termination,exit status = %d
    ", WEXITSTATUS(status));
            else if (WIFSIGNALED(status))
                    printf("abnormal termination, signal number = %d%s
    ",WTERMSIG(status),
                    #ifdef WCOREDUMP
                            WCOREDUMP(status) ? " (core file generated)" : "");
                    #else
                            "");
                    #endif
                    else if (WIFSTOPPED(status))
                            printf("child stopped, signal number = %d
    ", WSTOPSIG(status));
    }
    运行结果:
    [root@localhost apue]# vim exittest.c
    [root@localhost apue]# gcc exittest.c 
    exittest.c: In function ‘main’:
    exittest.c:28: 警告:被零除
    [root@localhost apue]# ./a.out 
    normal termination,exit status = 7
    abnormal termination, signal number = 6
    abnormal termination, signal number = 8
    

    如果一个进程有几个子进程,name只要有一个子进程终止,wait函数就返回。
    waitpid用于等待一个指定的进程终止。
    pid_t   waitpid(pid_t  pid,  int   *statloc,  int   options);
    如果pid = -1  等待任一进程终止,此时与wait等效。
    pid > 0 等待其进程ID与pid相等的子进程。
    pid  == 0  等待其组ID等于调用进程组ID的任一子进程。
    pid  < -1  等待组ID等于pid绝对值得任一子进程。















  • 相关阅读:
    生成树
    如何自定义百度网盘分享密码
    斯特林数入门
    各种反演难题训练集合
    LOJ[6247]九个太阳
    min25筛入门
    2020 Petrozavodsk Winter Camp, Jagiellonian U Contest-A-Bags of Candies
    ICPC WF 2018 C Conquer the World 征服世界
    dsu on tree
    生成函数入门级内容
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3503132.html
Copyright © 2011-2022 走看看