【Linux】之进程基础理解

版权声明: https://blog.csdn.net/spaceman_c/article/details/81814414
  • .进程的引入
    传统的程序是一系列的指令的结合,是一个静态的概念,无法描述程序在内存中的执行情况,及我们无法从程序中看出他何时执行,何时停顿,他与其他执行程序的关系;程序这个静态概念已经不能如实反应程序并发执行的过程,所以为了深刻描述程序动态执行过程的性质,所以引入进程

  • 进程的概念
    进程是一个具有一定独立功能的程序关于某个数据集合的一次运行过程,他是操作系统动态执行的基本单元

  • 进程和程序的区别****
    1, 程序是存放在磁盘上的,处于某个目录中的一个可执行文件,为了完成特 定任务的一系列指令的有序集合;
    2,进程是程序的一次动态执行过程,进程是操作系统分配资源的基本单位;
    3,进程是一个状态变化的过程,是暂时的,程序可以永久保存;
    4,组成不同:程序(数据+代码),进程(代码+数据+堆栈+pcb)
    5,进程是动态的,含有PCB 程序是死的,没有PCB;

    - 进程的标识符
    进程标识符:每一个进程都有一个非负整形标识的唯一进程ID(虽然是唯一的但是可以复用,当一个进程终止了,其进程ID就可以再次使用)
    系统中有一些专用的进程,ID为0的通常是调度进程,常常被称为交换进程,该进程是内核的一部分,他并不执行任何磁盘上的程序,因此也被称作是系统进程;进程 ID为1的是init进程,在自举过程中由内核调用,次进程负责在自举内核后启动一个UNIX系统,init通常读与系统有关的 初始化文件,并将系统引导到一个状态(多用户),init进程绝不会终止,他是一个普通的用户进程,但是他是以超级用户特权运行;ID为2的是页守护进程,此进程负责支持虚拟存储系统的分页操作;

  • 创建一个进程的一般工作
    1,分配一个PID(从小到大找没有使用的编号)
    [0 - /process/sys/kerne/pid_max](查看可以创建的最大进程数)
    (cat /proc/sys/kernel/pid_max)
    0 号进程是内核进程(是在操作系统中写死的),他创建 1 号进程
    0 号进程还将进程从物理内存搬到磁盘,和从磁盘搬到物理内存
    (磁盘在交换分区中放着

    2,分配PCB,拷贝父进程PCB 绝大部分数据
    3,给子进程分配资源
    4,复制父进程地址空间
    5,将子进程置成就绪状态,放入就绪队列

  • 怎样创建一个进程
    使用fork()会产生一个和父进程完全相同的子进程
    pid_t fork(void) 子进程返回0;父进程返回子进程ID;出错返回负一;
    但子进程在此后多会使用exec系统调用,出于效率考虑,linux中引入了“写时复制“技术,也就是只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。在fork之后exec之前两个进程用的是相同的物理空间(内存区),子进程的代码段、数据段、堆栈都是指向父进程的物理空间,也就是说,两者的虚拟空间不同,但其对应的物理空间是同一个。当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间,如果不是因为exec,内核会给子进程的数据段、堆栈段分配相应的物理空间(至此两者有各自的进程空间,互不影响),而代码段继续共享父进程的物理空间(两者的代码完全相同)。而如果是因为exec,由于两者执行的代码不同,子进程的代码段也会分配单独的物理空间。
    vfork创建子进程,与父进程内存数据共享;
    vfork保证子程序先运行,在他调用了exec或者exit之后父进程才可能被调度执行,如果在调用这两个函数之前子程序依赖于父进程的进一步动作,则会死锁;
    写时复制:父子进程共享的区域,内核将他们的访问权限改为可读,如果子进程和父进程中的任意一个试图修改这些区域,则内核之只为修改区域的那块内存制作一个副本
    写时复制:父子进程共享的区域,内核将他们的访问权限改为可读,如果子进程和父进程中的任意一个试图修改这些区域,则内核之只为修改区域的那块内存制作一个副本
    fork失败的两个原因:fork失败的两个原因:
    1,系统中有太多的问题(通常意味这系统出现了问题)
    2,实际用户ID进程总数超过了系统限制,
    僵尸进程 :在进程调用了exit之后,该进程并非马上就消失掉,而是留下了一个成为僵尸进程的数据结构,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。

  • 进程优先级
    用ps -l可以查看查看进程优先级
    PRI :进程优先权,代表这个进程可被执行的优先级,其值越小,优先级就越高,越早被执行
    NI :进程Nice值,代表这个进程的优先值
    PRI即进程的优先级,通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高
  • 进程状态
    这里写图片描述

  • 进程等待

    一个进程在终止时会关闭所有文件描述符,释放在用户空间分配的内存,但他的PCB还保留着,内核在其中还保留了一些信息,如果是正常终止则保持着退出状态,如果是异常终止,则保持着导致该进程终止的信号是哪个,这个进程的父进程可以wait和waitpid来获取这些信息,然后彻底清除掉这个进程

  • 进程程序替换
    exec函数:子进程调用exec函数,,该进程执行的程序完全替换成新程序;但是并不创建新进程,前后的进程ID并没有改变,exec只是用一个全新的程序替换了当前进程的正文,数据,堆,栈

  • 进程终止
    正常终止(5中)
    1,在main函数内调用return语句,等效于调用exit;
    2,调用exit函数,其操作包括调用各终止处理程序,然后关闭所有标准IO流
    3,调用_exit或_Exit函数
    4,进程的最后一个线程,在其启动例程中启动返回语句
    5,进程的最后一个线程调用pthread_exit函数
    异常终止(3中)
    1,调用abort(它产生SIGABRT信号)
    2,接到一个信号并终止(ctrl+c)
    3,最后一个线程对取消请求作出响应

  • 进程地址内存空间**
    这里写图片描述
  • 这里写图片描述
    每一个进程都各自拥有自己一份独立的内存空间(pcb),32位操作系统下是4G,进程在建立的时候,将会建立起自己的内存空间,哪些数据放哪里,都由都由进程控制表中的task_struct记录,task_struct中记录中一条链表,记录中内存空间的分配情况,哪些地址有数据,哪些地址无数据,哪些可读,哪些可写,都可以通过这个链表记录;
    每个进程的4G内存空间只是虚拟内存空间,每次访问内存空间的某个地址,都需要把地址翻译成实际物理内存地址,所有进程都共享同一块物理内存,每个进程只把自己目前需要的虚拟内存空间映射并存储到物理内存上,进程要知道哪些内存地址上的数据在物理内存上,那些不在,还有在物理内存上的那里,需要用页表来记录;页表分为两部分,第一部分记录此页是否在物理内存上,第二部分记录物理内存页的地址;
    进程使用虚拟内存中的地址,由操作系统协助相关硬件,把它“转换”成真正的物理地址。虚拟地址通过页表(Page Table)映射到物理内存,页表由操作系统维护并被处理器引用。

猜你喜欢

转载自blog.csdn.net/spaceman_c/article/details/81814414