【Linux】进程基本知识归纳

1.getpid函数

1.1函数原型

pid_t getpid(void); //返回当前进程Pid
pid_t getppid(void); //返回父进程Pid

  • pid:类似于身份证,代表每一个进程

1.2 例子

int main()
{
    __pid_t pid; // 定义一个变量接收Pid
    pid = getpid();
    printf("this process pid is %d , parent pid is %d\n",pid,getppid());

    return 0;
}

运行结果:

在这里插入图片描述

2.Fork函数

2.1函数原型

pid_t fork(void);

  • 作用:程序一开始只有一个进程,使用fork过后创建一个一模一样的进程,一起执行fork过后的代码,而fork之前的代码是由父进程进行执行的

返回值:fork函数拥有两个返回值

  • =0:当前进程为子进程
  • 0:当前进程为父进程
  • ‐1,出错

2.2图示

在这里插入图片描述

注:程序运行到fork后会执行创建两个一样的父子进程,父进程跟fork前的进程是一样的,包括pid与ppid,父进程运行结束过后,跳转到fork()返回值的位置,运行子进程,子进程是父进程的拷贝,执行代码直到结束

2.3例子

int main()
{
    __pid_t pid; // 定义一个变量接收Pid
    pid = getpid(); //获取进程的Pid

    fork(); //创建一个父进程,一个子进程,共同执行下面代码

    printf("current pid is %d\n",getpid());

    return 0;
}

运行结果:

在这里插入图片描述

画图表示:

在这里插入图片描述

  • 运行的顺序应该是:main函数开始经过fork执行父进程,父进程执行结束回到fork返回值的位置执行子进程,到最后程序结束

2.4例2

int main()
{
    pid_t pid; // 定义一个变量接收Pid
    pid_t pid2;
    pid = getpid();
    printf("before fork pid is %d\n",pid);

    fork();
    pid2 = getpid();

    if(pid == getpid())
    {
        printf("this is father : %d \n",getpid());
    }
    else
    {
        printf("this is chiild : %d \n",getpid());
    }

    return 0;
}

运行结果:

在这里插入图片描述

2.5返回值

fork会有两个返回值,大于0是代表此时是父进程,小于0代表此时是子进程

int main()
{
    pid_t pid; // 定义一个变量接收Pid
    pid_t pid2;
    pid = getpid();
    printf("before fork pid is %d\n",pid);

    fork();
    pid2 = getpid();

    if(pid == getpid())
    {
        printf("this is father : %d \n",getpid());
    }
    else
    {
        printf("this is chiild : %d \n",getpid());
    }

    return 0;
}

运行结果:

在这里插入图片描述

由此可以发现,父进程的fork返回值是子进程的PID,子进程的返回值是0

2.6作用域

int main()
{
    pid_t pid; // 定义一个变量接收Pid
    pid_t retpid;
    pid = getpid();
    int data  = 10;
    printf("before fork pid is %d\n",pid);

    retpid = fork(); //接收fork的返回值

    if(retpid>0)
    {
        printf("this is father : %d \n",retpid);
    }
    else
    {
        printf("this is chiild : %d retpid = %d \n",getpid(),retpid);
        data+=10;
    }

    printf("data is %d\n",data);

    return 0;
}

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PuqSJZXG-1684341251753)(进程.assets/image-20230512151904802.png)]

3.Fork应用

大多数应用场景在服务器:类似于QQ,有一个用户登录就会有一个新进程被创建

场景:模拟用户输入,如果输入的是1创建一个新进程,否则什么都不做

int main()
{
    pid_t retpid;
    int data = 0; // 用户输入
    while (1)
    {
        printf("plese input num:\n");
        scanf("%d", &data);
        if (data == 1)
        {
            retpid = fork(); // 输入为1创建一个进程
            if (retpid > 0)
            {
            }
            else if (retpid == 0)
            {
                while (1)
                {
                    printf("wati conncet: pid = %d\n", getpid());
                    sleep(3);
                }
            }
        }
        else
        {
            printf("nothing doing now\n");
        }
    }

    return 0;
}

运行结果:
在这里插入图片描述

4.Vfork函数

4.1vfork与fork的区别

  • 直接使用父进程的空间,不进行多余的拷贝
  • 先执行子进程,当子进程使用exit函数退出之后执行父进程
  • 存储空间是共享的

4.2 例1

int main()
{
    pid_t retpid;

    retpid = vfork(); // 接收vfork的返回值

    if (retpid > 0)
    {
        while (1)
        {
            printf("this is father pid = %d\n", getpid());
            sleep(2);
        }
    }
    else
    {
        while (1)
        {
            printf("this is chilid pid = %d\n", getpid());
            sleep(2);
        }
    }

    return 0;
}

运行结果:
在这里插入图片描述

4.3当子进程执行三次后退出

int main()
{
    pid_t retpid;
    int cnt = 0;
    retpid = vfork(); // 接收vfork的返回值

    if (retpid > 0)
    {
        while (1)
        {
            printf("this is father pid = %d\n", getpid());
            sleep(2);
            printf("cnt is %d\n",cnt);
        }
    }
    else if(retpid == 0)
    {
        while (1)
        {
            printf("this is chilid pid = %d\n", getpid());
            sleep(2);
            cnt++;
            if(cnt == 3)
            {
                _exit(-1);
            }
        }
    }
    return 0;
}

运行结果:

在这里插入图片描述

由于是vfork不进行拷贝,所以父进程可以使用子进程的资源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值