进程的挂起

   进程在一定的时间内没有任何动作, 称为进程的挂起

      

#include <unistd.h>

/*
 * 功能:
 *    进程挂起指定的秒数,直到指定的时间用完或 收到信号才解除挂起
 * return:
 *    进程挂起到sec指定的时间 返回0
 *    有信号中断 返回剩余秒数
 * 注意:
 *    进程挂起指定的秒数后程序并不会立即执行,系统只是将此进程切换到就绪态
 */
unsigned int sleep(unsigned int sec);

    进程的等待

          父子进程有时需要简单的进程间同步, 如父进程等待子进程的结束

       wait 函数

#include <sys/types.h>
#include <sys/wait.h>

/*
 * 功能:
 *   等待子进程终止,如果子进程终止,该函数会回收子进程的资源
 *   调用wait函数的进程会挂起,直到它的一个子进程退出或 收到一个不能被忽视的信号才被唤醒
 *   调用进程没有子进程或 它的子进程已结束,该函数立即返回
 * 参数:
 *    函数返回时,参数 status 中包含子进程退出时的状态信息 
 *    子进程的退出信息在一个 int 中包含了多个字段,用宏定义可以取出其中的每个字段
 * return:
 *   成功:子进程的进程号
 *   失败:-1
 * 取出子进程的退出信息:
 *   WIFEXITED(status)
 *     子进程是正常终止的,取出的字段值非零
 *   WEXITSTATUS(status)
 *     返回子进程的退出状态,退出状态保存在 status 变量的 8~16 位
 *     在用此宏前应先用宏 WIFEXITED 判断子进程是否正常退出, 正常退出才可以使用此宏
 * 注意:
 *    status:wait 的参数指向的整型变量
 */
pid_t wait(int *status);
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char *argv[])
{
    pid_t pid;
   
    pid = fork();
    if(pid < 0)
    {
        perror("fork");
    }

    if(0 == pid)
    {
        int i = 0;
        for(i = 0; i < 5; i++)
        {
            printf("this is son process\n");
            sleep(1);
        }
        _exit(2);
    }
    else
    {
        int status = 0;
        wait(&status);
        if(WIFEXITED(status) != 0)
        {
            printf("son process return %d\n", WEXITSTATUS(status));
        }
        printf("this is father process\n");
    }
    return 0;
}

 

      waitpid 函数

/*
 * 功能:
 *   等待子进程终止,如果子进程终止,此函数会回收子进程的资源
 * return:
 *   成功:子进程 ID
 *   出错:-1
 * pid 的值有以下几种类型:
 *   pid>0:
 *     等待进程 ID 等于 pid 的子进程。
 *   pid=0:
 *      等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid 不会等待它
 *   pid=-1:
 *     等待任一子进程,此时 waitpid 和 wait 作用一样
 *   pid<-1:
 *      等待指定进程组中的任何子进程,这个进程组的 ID 等于 pid 的绝对值
 * 
 *   status 参数中包含子进程退出时的状态信息
 * 
 * options 参数能控制 waitpid 的操作:
 *    0:
 *      同 wait, 阻塞父进程,等待子进程退出
 *   WNOHANG:
 *      没有任何已经结束的子进程,则立即返回
 *   WUNTRACED
 *       如子进程暂停了,此函数马上返回,并且不予以理会子进程的结束状态(跟踪调试,很少用到)
 * 返回值:
 *   成功:
 *     返回状态改变了的子进程的进程号,如 设置了选项 WNOHANG 并且 pid 指定的进程存在则返回 0
 *   出错:
 *     返回-1 当 pid 所指示的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid 就 
 *  会出错返回,这时 errno 被设置为 ECHILD
 */
pid_t waitpid(pid_t pid, int *status, int options);
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char *argv[])
{
    pid_t pid;
    pid = fork();

    if(pid < 0)
    {
        perror("fork");
    }

    if(pid == 0)
    {
        int i = 0;
        for(i = 0; i < 5; i++)
        {
            printf("this is son process\n");
            sleep(1);
        }
        _exit(2);
    }
    else
    {
        waitpid(pid, NULL, 0);
        printf("this is father process\n");
    }
    return 0;
}

    特殊进程
       僵尸进程(Zombie Process)

           进程已运行结束, 但进程的占用的资源未被回收

           原因: 子进程已运行结束, 父进程未调用 wait 或 waitpid 函数回收子进程的资源

      孤儿进程(Orphan Process)

           父进程运行结束, 但子进程未运行结束的子进程

      守护进程(精灵进程)(Daemon process)

          特殊的孤儿进程, 这种进程脱离终端, 在后台运行

进程的终止

    exit 函数   

#include <stdlib.h>

/*
 * 结束进程执行
 * 参数:
 *  status 返回给父进程的参数(低 8 位有效)
 */
void exit(int value)

  _exit 函数

#include <unistd.h>

/*
 * 结束进程执行
 * 参数:
 *   status:返回给父进程的参数(低8位有效)
 */
void _exit(int value)

     exit 为库函数, 而_exit 为系统调用