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

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值