【关于进程之fork函数和waitpid函数】

进程

进程和程序

1.程序:是一个静态的概念,表示有序指令的集合

2.进程:是一个动态的概念,表示程序运行的过程(运行过程包含:创建,调度,消亡)

1.程序中包含:
{
    1.数据段 ————(全局,静态,部分常量)
    2.代码段 ————(程序的指令)
    3.堆区.栈区
    4.进程控制块(PCB:task_struct):其实就是一个结构体来维护进程的
}

 进程的状态 

使用ps aux命令可以查看进程的状态

例如:

 <:高优先级 N:低优先级

 l:代表线程

1.运行状态:   R: 表示运行状态 +:前台运行 

2.等待态:进程进入资源等待过程,例如:getchar()等待终端输入

            (1)可中断:    S表示

            (2)不可中断  (软件不可以中断,但是硬件可以):D表示 这种状态一般表示与硬件正在进行交互

3.停止态:  T:表示停止 进程处于休眠状态

             T: 表示停止 进程处于休眠状态  需要通过特定信号将其唤醒 

              可以使用信号(Ctrl+Z)使进程进入停止态, 同样gdb断点调试时也处于停止态(追踪模式)       

4.僵尸态  Z:表示进程已经结束,但是资源没有完全回收

5.空闲状态: I 属于不可中断等待态D的内核线程,但是该内核线程可能实际上没有任何负载,该线程就是空闲状态

 虚拟内存

1.每一个进程都有自己的虚拟内存空间(32位系统4g)

2.虚拟内存与物理内存有映射关系,但是虚拟内存的大小和物理大小没有关系,与操作系统和cpu有关系

!前面都是基础点,下面我们进行实际应用(火速实操)

进程的系统调用

如果我们想实现一个功能同时输出"&&&&&&&&&"和"########"

 我们会发现程序会卡在第一个循环出不来,这时我们就要考虑多进程一起运行的该年,也可以说就是并发的的意思

那问题来了,我们要怎么样才能实现我们的想法?

不急,我们来引入多进程并发的思路,先介绍一个fork的函数

fork函数

fork函数通过系统创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做相同的事情,但是由于参数的位置或者变量不同,两个进程可以做不同的事情.

进程调用fork函数后,系统会给新的进程拷贝资源,资源就包括存储的数据和代码的空间,然后把原来的进程所有值复制到新的进程当中,相当于完全复制一个自己,这两个进程我们称之为父子进程,然后由于父子进程内部的代码不一样,因此他们各自实现的功能也不一样,自然结果也不一样.

头文件 #include <unistd.h>
fork(): 
pid_t fork(void)----进程创建函数
{
    宏观角度:
    该函数正确调用的话有两个返回值:一个>0的值一个==0的值.
    错误返回 -1
    pid_t p=fork();

    if(p==-1):错误发生,常见错误原因:资源不足开辟不了进程.
    else if(p==0):表示子进程
    else if(p>0):表示父进程
}

fork()一旦被调用,则子进程会拷贝所有父进程的所有资源(正文段(fork之后的)).数据段.代码段.堆.栈

其实fork函数其实是相当于新开辟了两个空间分别用来存放父进程和子进程,然后用条件来判断要执行父进程的内容还是子进程的内容.

pid==0时,是子进程,执行子进程的内容

pid>0时,是父进程执行父进程的内容

回到我们最开始的那个问题

先看代码

运行结果

现在就可以循环打印两个结果了

如果真的想要搞懂fork函数的原理 我们还要有关于内存的一个概念(因为fork这个函数拷贝其实是拷贝内存空间的原理嘛)

我再来提一下关于内存

物理内存 实际存在

虚拟内存 真的虚栈堆平时就放在上面

内核内存 半实半虚

 3个G的拷贝1个G的共享

但是PCB不会共享,每个新的进程都有新的PCB

有始有终,我们用fork开辟了进程就要会关闭进程.

进程资源回收

进程退出函数:exit()\_exit()

头文件 #include <unistd.h>

exit可以终止进程比return的级别高

关于返回值

exit(0) 正常结束

0的宏定义:EXIT_SUCCESS

exit(1) 进程异常结束

_exit 前面加下划线是比较暴力的退出 

资源回收函数

pid_t waitpid(pid_t pid, int *status, int options)    
        pid: pid > 0 只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,
                        只要指定的子进程还没有结束,waitpid就会一直等下去
                        
              pid == -1 等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样
              
              pid == 0  等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,
                        waitpid不会对它做任何理睬
                        
                        ps axj 可以查看组进程.
                        
              pid <  0  等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值
        status:  与wait一致
        
        options:  为 0 与wait函数一样,需要一直等待进程退出(阻塞).
                  为WNOHANG  不需要等待(不阻塞).        
        返回值: 正常返回子进程的进程号
        使用选项WNOHANG且没有子进程结束时:0
        错误: -1;
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞赴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值