Linux进程入门学习(三)-进程创建等待

来源:互联网 发布:php解密专家 编辑:程序博客网 时间:2024/05/18 03:39

1. 进程的创建

fork 函数用于创建子进程
头文件#include <unistd.h>
函数原型pid_t fork(void);
返回值

失败:-1成功:0 或者大于0 的正整数等于0:新的子进程返回值大于0:父进程中返回值大于0,该大于0 的值是子进程的PID

分析:

子进程相当是父进程的一个复制品,将父进程整个内存空间、包括栈、堆、数据段代码段等等父子进程有部分属性不一致:PID 记录锁挂起的信号父子进程运行顺序是不确定,有时可能是父进程先运行,也有可能是子进程先运行

示例:利用fork 创建子进程

/************************************************************************ File Name: m_fork.c* Author: 谢保成* E-mail: 2446603068@qq.com* Create Time: Mon 07 Aug 2017 02:12:36 AM PDT***********************************************************************/#include <stdio.h>#include <unistd.h>int main(){    pid_t pd;    int i=10;    printf("test for fork.\n");    pd = fork();    if(pd == -1)    {        printf("fork child PID fail.\n");    }    //子进程    else if(pd == 0)    {        printf("child pd = %d\n", pd);        printf("child process.\n");        i = 30;        printf("child i = %d\n", i);        while(1);    }    //父进程    else if(pd > 0)    {        sleep(1);        printf("parent pd = %d\n", pd);        printf("parent process.\n");        printf("parent i = %d\n", i);        while(1);    }    return 0;}

getpid 函数用于获取进程PID
头文件#include <unistd.h>
函数原型pid_t getpid(void);
返回值 成功,返回进程ID

getppid 函数用于获取父进程PID
头文件#include <unistd.h>
函数原型pid_t getppid(void);
返回值 父进程ID

示例:利用getpid 及getppid 函数打印进程的PID 及父进程PID

/******************************************************************************** File Name: t_fork.c* Author: 谢保成* E-mail: 2446603068@qq.com* Create Time: Mon 07 Aug 2017 02:38:44 AM PDT********************************************************************************/#include <stdio.h>#include <unistd.h>int main(){    pid_t pd;    int i=10;    pd = fork();    if(pd == -1)    {        perror("create failure!\n");        return -1;    }    //子进程    if(pd == 0)    {        printf("child pd = %d\n", pd);        printf("child process\n");        //打印自己的PID及父进程的PID        printf("child process  mypid = %d, myparentpid = %d\n", getpid(), getppid());        while(1);    }    //父进程    if(pd>0)    {        //睡眠1s,确保子进程先运行        sleep(1);        printf("parent pd = %d",pd);        printf("parent process\n");        //打印自己的PID 及父进程的PID        printf("parent process  mylist = %d, my parent PID = %d \n", getpid(), getppid());    }    return 0;}

2. 进程的等待

孤儿进程

父进程生成子进程,但是父进程比子进程先结束;子进程会变成孤儿进程,由系统1号init 进程进行接管。init 进程接管后,在该孤儿进程结束的时候,负责“收尸”,回收系统资源及进程信息。

僵尸进程

子进程已经退出,但是没有父进程回收它的资源(父进程生成的子进程,但是子进程比父进程先挂掉,如果父进程没有收回它的资源时,那么子进程挂掉后就变成了僵尸进程;应该尽量避免产生僵尸进程,可以在父进程调用wait 或者waitpid 进程回收)

wait 函数用于等待子进程
功能描述

进程一旦调用了wait,就立即阻塞自己,由wait 自动分析是否当前进程的某个子进程已经退出。如果让它找到了这样一个已经变成僵尸的子进程,wait 就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait 就会一直阻塞在这里,直到有一个出现为止。

头文件#include <sys/wait.h>
函数原型pid_t wait(int *stat_loc);
返回值

成功:被成功回收资源的子进程PID失败:-1

参数

int *stat_loc:返回状态

示例:

#include <stdio.h>#include <unistd.h>#include <sys/wait.h>int main(void){    pid_t pd;    int i = 10;    //创建子进程    pd = fork();    if(pd == -1)    {        perror("creat failure!\n");        return -1;    }    //子进程    if(pd == 0)    {        printf("child pd = %d\n",pd);        printf("child process\n");        //打印自己的PID 及父进程的PID        printf("child process mypid = %d, myparentpid = %d\n",getpid(),getppid());    }    //父进程    if(pd > 0)    {        pid_t return_pid;        int stat_loc;        //睡眠1s,确保子进程先运行        printf("parent pd = %d\n",pd);        printf("parent process\n");        //打印自己的PID 及父进程的PID        printf("parent process mypid = %d, myparentpid = %d\n",getpid(),getppid());        //等待子进程退出并回收它的资源        return_pid = wait(&stat_loc);        printf("return_pid = %d\n",return_pid);    }    return 0;}

waitpid 函数用于等待子进程
头文件#include <sys/wait.h>
函数原型pid_t waitpid(pid_t pid, int *stat_loc, int options);
参数

pid_t pid:指定等待的子进程PID<-1:等待组ID 为pid 绝对值的进程组内的任意子进程-1 :等待任意子进程=0 :进程组内的任意子进程>0 :等待PID 为pid 的子进程int *stat_loc:返回状态int options:    WNOHANG:当没有已退子进程时立即返回,即非阻塞    WUNTRACED:当有子进被暂停立即返回    WCONTINUED:当有子进程收到信号立即返回    若写0,就是阻塞,相当wait(int *stat_loc);返回状态可以通过宏来

返回值

-1:执行失败0:指定了选项WNOHANG,且没有已退子进程>0:成功回收了PID 等于返回值子进程的资源

实例

#include <stdio.h>#include <unistd.h>#include <sys/wait.h>int main(void){    pid_t pd;    int i = 10;    //创建子进程    pd = fork();    if(pd == -1)    {        perror("fork failure!\n");    return -1;    }    //子进程    if(pd == 0)    {        printf("child pid = %d\n",pd);        //打印自己的PID 及父进程的PID        printf("child:PID=%d, PPID=%d\n",getpid(),getppid());    }    //父进程    if(pd > 0)    {        pid_t return_pid;        int stat_loc;        printf("parent pid = %d\n",pd);        //打印自己的PID 及父进程的PID        printf("parent:PID=%d, PPID=%d\n",getpid(),getppid());        //非阻塞不等待子进程退出        return_pid = waitpid(pd, &stat_loc, WNOHANG);        printf("return_pid = %d\n",return_pid);    }    return 0;}
原创粉丝点击