Linux之循环创建多个子进程

创建进程
进程控制原语
fork函数
 pid_t fork(void);  //创建一个子进程
【返回值】有两个  一个进程 --> 两个进程  --> 各自对fork做返回
- 返回子进程的pid(非负整数 > 0)  (父进程)
- 返回0                             (子进程)

创建单个子进程
【练习】

#include <stdio.h>
#include <unistd.h>
//创建单个子进程
int main()
{
    pid_t pid;
    printf("XXXXXXXXXXXXXXXXXX\n");
    pid = fork();
    if(pid == 0) //子进程
    {
        printf("I'm child, pid = %u, ppid = %u\n", getpid(), getppid());
    }
    else if(pid > 0)
    {
        sleep(1);
        printf("I'm parent, pid = %u, ppid = %u\n", getpid(), getppid());
    }
    else
    {
        return -1;
    }
    printf("YYYYYYYYYYYYYYYYYYYYYYY\n");
    return 0;
}


【运行结果】


循环创建N子进程
【代码】

#include <stdio.h>
#include <unistd.h>
//循环创建多个子进程
int main()
{
    pid_t pid;
    printf("XXXXXXXXXXXXXXXXXX\n");
    int n = 3;
    int i;
    for(i = 0; i < n; i++)
    {
        pid = fork();
        if(pid == 0) //子进程
        {
            printf("I am %d child, pid = %u\n", i + 1, getpid());
        }
        else if(pid > 0)//父进程
        {
            sleep(1); //让子进程先输出
            printf("I am %d parent, pid = %u\n", i + 1, getpid());
        }
    }
    return 0;
}


【运行结果】


【分析结果】从结果上看,远远不止创建了3个子进程
简单想,for(i = 0; i < n; i++){ fork(); }即可。但是这样创建的是N个子进程吗?
【图解】

 

【修改代码】父进程负责fork,子进程什么也不做

#include <stdio.h>
#include <unistd.h>
//循环创建多个子进程
int main()
{
    pid_t pid;
    printf("XXXXXXXXXXXXXXXXXX\n");
    int n = 3;
    int i;
    for(i = 0; i < n; i++)
    {
        //父进程负责fork,子进程什么也不做
        pid = fork();
        if(pid == 0) //子进程通过break
        {
            break;
        }
    }
    
    if(i < n)
    {
        sleep(i); // i = 0,1,2…… //保证子进程按找顺序输出
        printf("I am %d child, pid = %u\n", i + 1, getpid());
    }
    else  //i = n
    {
        sleep(i);  //保证子进程先输出,父进程先睡眠 n 秒
        printf("I am parent\n");
    }
    return 0;
}


【运行结果】


上面的代码中,我们用sleep函数保证了子进程的顺序输出,并且父进程在所有子进程运行结束之后再运行。试想一下,当我们去掉所有sleep函数之后,运行结果会和上面一致吗?

 

此时你会发现结果完全不同,最后程序像还没有结束一样,一直有光标在最后一行闪。当我们在光标处输入ls命令,发现ls命令可以正常执行。当执行完ls之后,shell回到了正常的状态

 

那么为什么会出现这样的执行结果呢?
【光标问题】
【关键】shell进程(父进程的父进程)搅和进来。当我去掉所有的sleep函数之后,父进程和子进程以及shell进程之间共同抢夺CPU,shell进程并不知道父进程又创建了子进程
shell的正常状态,阻塞在这里等待用户输入,接受命令解析


当我输入一个 ./a.out,就是要把当前程序运行,这时shell进程会把自己切到后台去,把前台(终端)交给 a.out这个进程


那shell进程什么时候收回前台的使用权?a.out运行结束

那shell进程怎么判断a.out结束了呢?a.out只要return了,shell进程就要抢占前台,然后在进入到正常状态,等待用户输入

 

但是shell进程不知道还有子进程,当父进程执行完(打印了 I am parent),shell进程抢占了前台,恢复到正常状态,此时子进程3用了终端,所以这句话( I am 3 child, pid = 19810)就没打印到下一行的行首,而是直接打印到光标的后面的位置上,打印完之后,做了个换行,光标移到下一行起始位置,这时候子进程2又抢占了终端,在光标之后打印了一句话……


当3个子进程打印结束后,光标停在子进程1打印结束的下一行行首,等待用户输入


所以我们第一加了sleep函数保证父进程在所有子进程结束之后再退出,所以shell是正常的状态,不会出现上面的情况
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/qq_41033011/article/details/107480456

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值