进程(一)--- 进程概念

程序和进程

什么是程序?

  • 程序就是一个被动的实体(需要被用户指定执行),就是一个存储在磁盘上的文件包含了一系列的指令(被称作可执行文件)。

什么是进程?

当可执行文件被加载进内存后,程序就变成了进程。这个可执行文件包含了指令,当加载进内存后,cpu就可以执行这些指令,直到所有指令执行完成。
进程是一个活动的实体,这个实体中包含了程序计数器用来指明下一条需要执行的指令

程序计数器(pc--programer counter):是一个cpu中的寄存器,里面存放了下一条要执行指令的内存地址,通常,cpu取完一条指令之后会将PC寄存器的值加 "1",用来计算下一条要执行指令的地址。

当将一个程序代码加载进内存,并将第一条指令地址写入pc寄存器之后,进程就创建完成了。

进程再内存中的分布

当进程被加载进内存后,程序会将内分成几块区域----> 代码段、数据段,堆,栈

int global = 100; //全局变量

void f(int x,int y){ //
  int* p = malloc(100);
  return;
}

void g(int a){ //
  f(a,a+1);
  return;
}
int main(){
  static int i = 10; //静态变量
  g(i);
  return 0;
}
  1. 以上代码编译后会变成二进制指令,这些指令会放在text 区域,这个区域是只读区域。

  2. 这个代码的入口是 main 函数, 先将主函数的返回地址写入栈,发现主函数中有staic 变量i和全局变量global,则将这两个变量存入data区域

  3. 调用g() 函数,将a 放入stack 上,接着将g()函数的返回值(在main函数内的地址,方便g()函数返回的时候继续执行main函数接下来的代码)也压入栈

  4. g()函数会调用f()函数,因此同理,将x,y,p 三个局部变量放入栈中,接着将f的返回值放入栈中

  5. p变量被动态分配了一块内存,因此将p变量放入到heap上,同时分配100个字节

  6. f函数执行完返回:将f()函数的返回地址读取出来,由于函数要返回了,因此需要将f函数中的局部变量地址清除,以及f的返回值也清除,接着执行g()函数

  7. g()函数返回,取出g()函数的返回地址,定位到main函数中的g(i)那段代码,同时清除g()函数返回地址和g()函数内部局部变量

  8. main函数返回,清空堆内存(由于没有free p变量,p变量要等到函数退出才会销毁)

并发的进程

并发与并行

再同一个时间发生或者存在的两个或多个事件被称为并发(concurrency)

再同一个时间同时运行的两个或多个事件被称为并行(parallel)

当再单核机器上,同时创建多个程序,那就是并发,这两个程序同时存在,但是再同一个时间只有一个进程再运行,如果在2核cpu上,执行两个进程,两个进程分别由不同的cpu来执行,那么这种就叫做并行,因为他们再同一时间都在运行。

cpu上的并发

cpu再执行程序的时候会被划分成一个个时间片,由操作系统来调度再这个时间片上由哪个进程来由cpu执行。当一个进程因为执行的时间到了而被另外一个进程顶替的占有cpu,这个过程叫“进程切换

其中实线代表的是进程占有cpu,虚线代表的是进程没有占有cpu

进程状态

根据上面并发的知识知道,进程并不是一直都在运行的,而且会由操作系统进行调度,有时执行,有时并没有执行,因此需要给进程标记上他当前的状态,好让操作系统可以来调度管理进程。

三种基本状态

进程总共有五种状态,其中两种是创建和终止,运行中的进程一般只在以下三个状态切换

  • 就绪态(ready):进程的代码再cpu上运行
  • 运行态(running):进程具备运行条件,等待分配cpu
  • 等待态(waiting):进程再等待某些时间的发生(比如IO操作结束或者一个信号),不具备运行条件==

通过上面图可以看出:

  • running----> ready: 运行中的进程时间片用完或者有高优先级的进程到达会进入就绪态
  • running----> waiting: 运行中的进程再遇到IO或者事件阻塞(比如将字符串输出到显示器的时候,由于这些操作很慢,进程就会被切换成等待)
  • ready-----> running: 当操作系统开始调度分配进程的时候,进程就有就绪态转换为运行态
  • waiting----->ready :当遇到IO或者某些事件完成
posted @ 2022-04-11 19:32  zhqqqy  阅读(102)  评论(0编辑  收藏  举报