操作系统篇-进程管理和中断

以下针对java来说明

1. 进程 线程 纤程

在这里插入图片描述

进程和线程区别

进程就是一个程序运行起来的状态,线程是一个进程中的不同的执行路径。
进程是OS分配资源的基本单位,线程是执行调度的基本单位。分配资源最重要的是:独立的内存空间,线程调度执行(线程共享进程的内存空间,没有自己独立的内存空间)

线程在Linux中的实现

《Linux内核设计与实现》第三版28页
线程在Linux就是一个普通的进程,只不过和其他进程共享资源(内存空间,全局数据等)

其他系统都有各自所谓的LWP的实现 Light Weight Process(轻量级进程)

纤程

在这里插入图片描述
即:用户空间的线程

为什么需要纤程:
java启动线程,在操作系统级别,就是启一个LWP。这是重量级线程。因为java启动线程需要向操作系统申请资源,和操作系统内核打交道,需要系统调用。
而纤程是线程中的线程,对应图最上面蓝色框,在用户空间,不需要向操作系统申请。
纤程处于线程内部,非常轻量级,可以在线程中快速切换。JVM自己管理,自己实现调度,自己切换,与操作系统无关。

纤程优势:

  1. 占有资源很少 OS : 线程:1M vs Fiber:4K
  2. 切换比较简单
  3. 启动很多个10W+

纤程的应用场景:
很短的计算任务,不需要和内核打交道,并发量高

2. 进程

Linux中也称为task,是系统分配资源的基本单位
资源包括:独立的地址空间,内核数据结构(进程描述符…),全局变量, 数据段…
Linux进程描述符:PCB (Process Control Block),用于Linux的进程管理(线程有他的PCB)

僵尸进程

ps -ef |grep defunct (defunct表示无用的僵尸进程)

父进程产生子进程后,会维护子进程的PCB结构,子进程退出后,由父进程释放,如果父进程没有释放,那么子进程会成为一个僵尸进程(defunct)

孤儿进程

子进程结束之前,父进程已经退出,就会产生孤儿进程,孤儿进程会成为Init进程的子进程,由1号进程维护 (在图形化Linux中是1457号线程)

调度策略

早期Linux 2.5 内核用的是Unix O(1)调度策略,按固定的时间片给程序

Linux内核2.6.23 采用CFS调度策略:Completely Fair Scheduler
按优先级分配时间片的比例,记录每个进程的执行时间,如果有一个进程执行时间不到他应该分配的比例,优先执行。 (比如有的程序开始没做什么就会让出给其他程序,当开始需要做的时候,优先执行)

默认调度策略:
实时进程 > 普通进程
实时进程优先级分高低 - FIFO (First In First Out),优先级一样的时候 - RR轮询(Round Robin)
普通进程: CFS

其中等级最高的是FIFO,这种进程除非自己让出CPU否则Linux会一直执行它,除非更高级的FIFO和RR抢占它
RR只是这种这种进程中是同级别FIFO中的平均分配 ---- 比如FIFO中有两个都是90优先级的进程,这时候按照RR执行。
只有实时进程主动让出,或者执行完毕后,普通进程才有机会运行。

3. 中断

硬中断

硬件和操作系统通信的一种机制
在这里插入图片描述
执行过程:
键盘 -----中断控制器(通知cpu一个中断信号来了)--------cpu(在内存中固定位置找处理程序)-------执行程序(查中断向量表,把中断信号给kernel)-------kernel(根据中断信号找程序)----------中断处理程序(已经写好的一堆处理程序,有处理键盘的,有处理打印机的)-----------------先由OS内核处理(上半场)------------再由应用程序处理(下半场)

软中断(80中断)

中断向量表特殊的符号
系统调用:int 0x80 (INT是用于x86处理器的汇编指令) 或者 sysenter原语(现在的cpu在硬件级别直接支持,汇编码)

通过ax寄存器填入调用号(比如1代表exit函数,2代表fork函数)
参数是通过bx cx dx si di传入内核
返回值通过ax返回

系统调用实现的hello world代码:

;以下例子主要调用了内核空间的write函数 
;write(int fd, const void *buffer, size_t nbytes) 
;fd文件描述符,buffer要写的内容,nbytes内容的长度

.section .data ;数据段声明
msg:
        .ascii "Hello world!\n"
.section .text ;代码段声明
.globl _start ;指定入口函数
_start: ;在屏幕上显示一个字符串
        movl $4, %eax ;系统调用sys_write
        movl $1, %ebx ;文件描述符1,std_out
        movl $msg, %ecx
        movl $13, %edx
        int $0x80
        movl $1, %eax ;系统调用sys_exit
        movl $0, %ebx
        int $0x80

系统调用是通过int 0x80来实现的,eax寄存器中为调用的功能号,ebx、ecx、edx、esi等等寄存器则依次为参数,从 /usr/include/asm/unistd.h中可以看到exit的功能号_NR_exit为1,write(_NR_write)功能号为4,因此第一个int 0x80调用之前eax寄存器值为4,ebx为文件描述符,stdout的文件描述符为1,ecx则为buffer的内存地址,edx为buffer长度。第二个int0x80之前eax为1表示调用exit,ebx为0表示传入参数0。

注:eax 是32位的,ax是16位的

java中例子
java读网络 – jvm read() – c库read() - > 内核空间 -> system_call() (系统调用处理程序)-> sys_read()

  • 39
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 33
    评论
当一个进程访问的页面或段不在主存储器中时,操作系统会产生缺页中断或缺段中断操作系统需要处理这些中断,以便将缺失的页面或段调入主存储器,使得进程可以继续执行。下面分别介绍缺页中断和缺段中断的处理过程: 1. 缺页中断处理: (1)操作系统会保存当前进程的上下文,并将控制权转移到内核态。 (2)操作系统会检查进程请求的页面是否可用,如果可用,则直接将页面映射到进程的地址空间中,并将控制权返回给进程。 (3)如果请求的页面不可用,则操作系统会选择一个页面将其从主存储器中替换出去,并将请求的页面从硬盘中读入主存储器中,然后将其映射到进程的地址空间中,并将控制权返回给进程。 (4)操作系统会更新页表,记录页面的状态和位置信息。 (5)最后,操作系统会恢复进程的上下文,使其继续执行。 2. 缺段中断处理: (1)操作系统会保存当前进程的上下文,并将控制权转移到内核态。 (2)操作系统会检查进程请求的段是否可用,如果可用,则直接将段映射到进程的地址空间中,并将控制权返回给进程。 (3)如果请求的段不可用,则操作系统会选择一个段将其从主存储器中替换出去,并将请求的段从硬盘中读入主存储器中,然后将其映射到进程的地址空间中,并将控制权返回给进程。 (4)操作系统会更新段表,记录段的状态和位置信息。 (5)最后,操作系统会恢复进程的上下文,使其继续执行。 需要注意的是,不同的操作系统对于缺页中断和缺段中断的处理方式可能会有所不同。例如,在Linux操作系统中,缺页中断的处理过程涉及到页面置换算法的选择,而缺段中断的处理过程则需要考虑段的权限和保护等问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

lovelife110

你的鼓励是我创作的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值