进程的执行过程


前言

本文主要记录一下进程的执行过程,并通过一些例子,帮助进一步理解这个过程。


一、进程的执行过程

  • 任意时刻,只有一个事件被执行,其他的进程会被放入READY和WAIT队列中,其中READY队列存放的是,当前时刻将要被执行的事件,WAIT队列存放的是,直到条件满足的阻塞的事件。
  • 当前执行的进程进入等待状态时,会进入WAIT队列,接着执行下一个READY进程。
  • 当所有的进程进入等待队列时,执行仿真时间。
    在这里插入图片描述

二、进程的示例

2.1 示例1所有进程必须有限或者与时钟相关

示例1代码如下所示,问这段代码能否正常工作。
答案是否,原因是在第一个进程中,没有与时间相关的阻塞进程,导致仿真一直卡在0时刻,等待第一个进程中的条件满足。
在这里插入图片描述
修改后,能够正确执行的代码如下,在多进程中,所有的进程必须有限或者与时钟相关。
在这里插入图片描述

2.2 示例2多进程共享变量

示例2代码所示,两个子进程放入了fork-join中,子进程1中的a计算基于b的值,子进程2中的b计算基于a的值,问a和b的最后结果是多少。
结论是a=4, b=8,原因是fork–join会按顺序将两个begin-end包括的子进程放入READY队列,先执行第一个进程得到a=4,再执行第二个进程得到b=8。
在这里插入图片描述

2.3 示例3仿真在0时刻结束

示例3代码如下图所示,task send被fork–join_none包括起来,每次调用都放入后台,不阻塞主进程,而主进程在initial中,通过for循环连续调用16次send,问send能否被执行16次。
答案是否,而且仿真在0时刻就结束了,原因是子进程的任务没有在主进程中被阻塞,主进程initial块在0时刻仿真就结束了。
在这里插入图片描述
要想子进程能够执行16次,需要在主进程中做阻塞处理,保证子进程都结束了,仿真才结束,修改方案有两个,其一是利用wait fork,等待所有的子进程都结束后,再结束仿真,其二是设置一个变量,子进程执行完就加1,主进程中等到该变量到16的时候,再结束仿真。
具体代码实现,参考如下:
在这里插入图片描述

2.4 示例4仿真变量保持不变

接着示例3中的代码,利用wait fork的解决方案,跑完仿真后会发现,传过去的i值一直是16。
在这里插入图片描述
通过展开for循环后,会发现原因是,for循环中发送的16次send使用的是同一个变量i,进程执行的时候,首先会将16个send挨个放入READY队列中,然后再去执行send任务的时间阻塞实体,当执行的时候此时的i是16,这就导致16个send传递的i值都是16,图解如下:
在这里插入图片描述
要解决上面的问题,可以采用local变量,在for循环中,嵌入一个本地变量index,将i的值赋给这个index,然后再将index传递发送出去。
在这里插入图片描述
使用了本地变量后,展开的for循环如下所示,实现了0到15的send。
在这里插入图片描述


总结

本文主要记录一下进程的执行过程,并通过几个示例,进一步加深对进程的理解。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值