嵌入式技术笔记(十二):进程控制

进程控制

  1. 什么是进程:进程是可并发执行的程序,是一个在数据集合上的运行过程
    当一个程序开始执行后,在开始执行到执行结束的这段时间里,它内存的部分称为进程。(进程是计算机中资源分配的最小单位
    每个进程都是个独立的空间。
    通俗讲:
    程序:在硬盘上的可执行文件
    进程:在执行中的程序

  2. 什么是并发
    多进程同时运行,多个任务同时执行

  3. 虚拟内存(通过映射形成)

  • Linux虚拟内存管道技术:
  • 物理内存:实际在处理器中的内存模块(几百M)
    将硬盘中的一部分存储单元拿来当内存使用(4G——受操作系统的寻址范围的影响) 正常范围:0x00000000 ~ 0xffffffff
  • 操作系统:内核空间 和 用户空间

内核空间:存放高地址,其中驱动就是运行在此部分空间中(1G)
用户空间:普通的应用程序代码运行在此部分空间中(3G)
好处:
1、有效防止内核空间被破坏
2、防止被恶意窥探:(虚拟内存是通过物理内存映射形成,而且数据在数组中是连续的,但指针存储的是内存地址,地址顺序是乱的,所以无法通过虚拟内存窥探存储的信息)
3、拓展内存空间

  • 数组在内存中的存储特点:连续
    指针定义:内存地址,指针变量是用来存放内存地址的变量,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。
    指针作用:通过指针不仅可以对数据本身,还可以对存储数据的变量地址进行操作。指针就是内存地址,指针变量是用来存放内存地址的变量。

  • 虚拟内存的组成
    虚拟内存 = 物理内存 + 偏移量

  1. 进程的分类
  • 守护进程
  • 批处理进程
  • 交互进程
  1. 进程的属性
    进程ID(PID):是唯一的数值,用来区分进程
    父进程的ID:PPID
    启动进程的用户ID:UID
    进程的状态:运行R,休眠S,僵尸进程Z
    进程优先级
    进程占用资源的大小(内存,cpu)

  2. 进程控制模块PCB:数据结构
    进程号

ps命令查看Linux系统中的进程
l:长格式输出
u:按用户名和启动时间的顺序来显示进程
f:用树状格式来显示进程
a:显示所有用户的所有进程
x:显示无控制终端进程 (通常aux一起用)
ps和ps -l

  • ps -u命令:
    %CPU:占CPU的百分比
    %MEN:占进程的百分比
    VSZ:虚拟内存大小
    RSS:物理内存大小
    TTY:终端ID(终端的次要装置号码5)
    STAT:进程状态
    X表示被杀死的进程,T表示被追踪的进程
    s代表进程的引导者
    START:进程的开始时间
    TIME:进程消耗CPU的时间
    COMMAND:(命令)参数的名称
    ps -u
    ps -x命令:
    < 表示优先级高,如图I<表示I的优先级高
    在这里插入图片描述
  • kill:kill 进程号
    kill -9 进程号:强制终止(-9 杀死僵尸进程)
    pkill:pkill 程序名 = killall:killall -9 程序名
    在这里插入图片描述
    xkill:在桌面上杀死图形化界面
    renice:改变进程的优先级,通过改变进程ID(PID)来改变进程的优先级
    renice 谦让度 PID
  1. 进程的状态转换
    (1)就绪:当进程已分配到除cpu以外的所有必要资源,只要获得处理器就可以立即执行
    (2)执行:已经获得处理器,器程序正在处理器上执行
    (3)阻塞:正在执行的进程,由于等待某个事件的发生而无法执行时,便放弃处理机会而处于阻塞状态
    并发的本质:时间片轮询
    在这里插入图片描述
    虚拟内存与进程的关系如下:
    在这里插入图片描述

  2. Linux进程调度

  • FCFS也叫FIFO,先来先处理
    缺点:对于短的任务可能变得非常缓慢
  • 时间片轮询算法:周期性的切换,总体时长比FIFO短
    缺点:若时间片选择不合适(过大),会导致时间过长
  • STCF:短任务优先算法
    分为抢占式和非抢占式
    抢占式:允许将逻辑上可继续运行的在运行过程暂停的调度方式
    非抢占式:让进程运行直到结束或阻塞的调度方式
    缺点:短任务优先会导致长任务无法抢占CPU资源,无法执行
  • 银行家算法:能够避免死锁
    每一个新进程进入系统时,必须声明需要每种资源的最大数目,其数目不能超过系统所拥有的的资源总量。当进程请求一组资源时,系统必须首先确定是否有足够的资源分配给该进程,若有,再进一步计算在将这些资源分配给进程后,是否会使系统处于不安全状态如果不会才将资源分配给它,否则让进程等待。
    优先级反转(优先级保护机制、设置保护区)
  1. 创建一个进程
    fork()函数:它有两个更返回值
    其中0:子进程 -1:失败 >0:父进程
    父子进程

代码如下:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    pid_t pid = fork();
    if(-1 == pid)
    {
	perror("fork error!");
	exit(1);
    }
    if(0 == pid)
    {
	printf("This is child: pid: %d; ppid: %d\n",getpid(),getppid());
    }
    else
    {
	printf("This is father: pid: %d; ppid: %d\n",getpid(),getppid());
    }
}

运行结果:
从运行结果可以看出父进程和子进程的关系,即子进程的父进程号等于父进程的进程号。
在这里插入图片描述

getpid()函数:获取当前进程号
getppid()函数:获取当前父进程号

代码如下:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int a = 5;

int main()
{

    pid_t pid = fork();
    if(-1 == pid)
    {
	perror("fork error!");
	exit(1);
    }
    if(0 == pid)
    {
	a = a * 2;
	printf("This is child: pid: %d; ppid: %d  a = %d\n",getpid(),getppid(),a);
    }
    else
    {
	int b = a - 1;
	printf("This is father: pid: %d; ppid: %d  b = %d\n",getpid(),getppid(),b);
    }
}

运行结果如下:
父进程的结果是4,即5-1;子进程的结果是10,即5*2
父进程和子进程都用全局变量a的初始值!
在这里插入图片描述
出现这种现象的原因:父进程和子进程跑在不同的内存空间中:父进程和子进程有自己独立的内存空间(所以不能用全局变量通信)

子进程会复制父进程的堆栈数据空间,复制是在调用fork函数后发生的。

早期:fork函数运行后,子进程会复制父进程的堆栈数据空间
优化:读时不管,写时复制
代码如下:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>


int main()
{
    int a = 5;
    int b = 100;

    pid_t pid = fork();

    if(-1 == pid)
    {
	perror("fork error!");
	exit(1);
    }
    if(0 == pid)
    {
	a = a * 2;
	printf("This is child: a = %d; a addr:%x; b = %d; b addr:%x\n",a,&a,b,&b);
    }
    else
    {
	a = a - 1;
	printf("This is father: a = %d; a addr:%x; b = %d; b addr:%x\n",a,&a,b,&b);
    }
}

运行结果如下:
发现父进程和子进程的地址一样
父进程和子进程的地址一样
fork函数创建的父子进程关系是竞争关系,不能判断是谁先动
如下图:
父子进程是竞争关系

  • vfork():创建一个进程
    与fork的不同之处:
    1、保证子进程先动
    运行截图:
    在这里插入图片描述
    如图会出现“Segmentation fault (core dumped)”这种段错误。
    产生的原因:使用了野指针。因为子进程和父进程要通过指针才能调用栈里的数据,所以会产生野指针。
    解决办法:在子进程的最后用exit(1)退出
    2、当子进程调用exit()函数后,父进程往下执行
    3、不会继承父进程的页面
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值