Linux进程管理相关函数

启用新的进程

  • system函数

    system函数使用简单,因为它必须用一个shell来启动需要的程序,因此对shell的安装情况和环境的依赖很大,并且有一些其它的缺陷,所以system函数的使用率并不高。
    如下例程system1:

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

int main()
{
    printf("Runing test...\r\n");
    system("ps");
    printf("Done.\r\n");
    exit(0);
}

输出结果:

$ ./test
Runing test...
  PID TTY          TIME CMD
 5843 pts/19   00:00:00 bash
 8246 pts/19   00:00:00 test
 8247 pts/19   00:00:00 sh
 8248 pts/19   00:00:00 ps
Done.

因为system函数用一个shell来启动想要执行的程序,所以可以放到后台来执行,修改system1.c代码

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

int main()
{
    printf("Runing test...\r\n");
    system("ps &");
    printf("Done.\r\n");
    exit(0);
}

输出结果:

$ ./test1
Runing test...
Done.
$
  PID TTY          TIME CMD
 5843 pts/19   00:00:00 bash
 9601 pts/19   00:00:00 ps

这样的打印信息会使用户比较迷茫。因为是后台程序,ps命令一启动后shell就返回了。

  • 替换进程映像

    exec系列函数可以直接替换原先进程,去执行新的指令,新进程的PID、PPID和nice值也完全一样,但是exec函数后面的代码将不会在执行,因为它不会再返回原先的进程中。

  • 复制进程映像

    要想让进程同时执行多个函数,我们可以使用线程或从原程序中创建一个完全分离的进程,后者就像init的做法一样,而不像exec调用那样用新程序替换当前执行的进程。复制一个进程可以使用fork()函数,复制进程时可以使用wait()函数,它将暂停父进程直到它的子进程结束为止。

    扫描二维码关注公众号,回复: 178806 查看本文章
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    pid_t pid;

    printf("fork program starting\r\n");
    pid = fork();
    printf("fork pid is: PID=%d\r\n", pid);

    switch(pid)
    {
        case -1:
            perror("fork failed");
            exit(1);

        case 0:
            printf("This is the child\r\n");
        break;

        default:
            printf("This is the parent\r\n");
        break;
    }

    if(0 != pid)//parent progress
    {
        int stat_val;
        pid_t child_pid;

        child_pid = wait(&stat_val);

        printf("child has finished: PID=%d\r\n", child_pid);
        if(WIFEXITED(stat_val))
            printf("Child exited with code %d\r\n", WEXITSTATUS(stat_val));
        else
            printf("Child terminated abnormally\r\n");
    }
    exit(0);
}

代码为fork函数和wait函数配合,来新建一个进程,运行结果为

$ ./wait 
fork program starting
fork pid is: PID=16207
This is the parent
fork pid is: PID=0
This is the child
child has finished: PID=16207
Child exited with code 0

如果fork了多个子进程,可以固定的等待某个子进程是否结束,使用waitpid函数,函数原型如下:

pid_t waitpid(pid_t pid, int *stat_loc, int options);
 pid参数指定需要等待的子进程的PID。如果它的值为-1,waitpid将返回任一子进程的信息。
 若stat_loc不是空指针,waitpid将会把状态信息写入它所指向的位置。
 options参数用来改变waitpid的行为,其中最有用的一个选项是WNOHANG,它的作用是防止waitpid调用将调用者的执行挂起。因此,如果想让父进程周期性的检查某个子进程是否终止,可以用下面的调用方式:`waitpid(child_pid, (int *)0, WNOHANG)`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
  • 僵尸进程

    使用fork函数创建进程,当子进程终止时,它与父进程之间的联系还会保持,直到父进程也正常终止或父进程调用wait后才结束。因此,子进程先结束后,进程表中代表子进程的表项不会立刻释放。虽然子进程已经不在运行,但它仍然存在于系统中,因为它的退出码还需要保存起来,以备父进程今后的wait调用使用,这时它将成为一个僵尸进程。
    如果父进程异常终止,子进程会自动把PID为1的进程(即init)作为自己的父进程,僵尸进程会一直保留,直到被init进程发现并释放。

猜你喜欢

转载自blog.csdn.net/yk150915/article/details/79072870