关于线程切换问题的一些思考总结


    最近被问到一个问题,线程是如何切换的?线程本身的切换过程是可以几句话说清的,但其后是关于操作系统最核心的进程和线程的问题,我有回顾了一下操作系统,做了一些总结。

1. 进程、内核级线程、用户级线程

  1. 本质上来说,三者都是执行一个指令序列,都属于CPU的管理范畴;
  2. 要执行一个序列,除了分配栈、创建数据结构记录执行位置外,还要分配内存等资源,这就是进程的概念;
  3. 将进程中的资源和执行序列分离以后就引出了线程概念,进程中的执行序列实际上就是一个内核级线程;
  4. 内核级线程就是操作系统在一套资源下创建的可以并发执行的多个序列;
  5. 而上层应用程序创建的多个指令执行序列,执行程序所需的资源已经在创建进程时分配好了,这就是用户级线程。

2. 用户级线程的切换

  1. 用户级线程的切换就是在切换位置调用yield()函数;
  2. 函数的基本工作就是找到下一个进程的TCB,将当前寄存器ESP的值保存在当前线程TCB中,从下一线程的TCB中取出保存的ESP的值赋给ESP寄存器;
  3. 切换到新栈以后,通过压入栈的返回值,将PC指针切换到下一个线程要执行的指令处;
  4. 线程切换时还需要保存和恢复一些现场,主要就是一些通用寄存器。
Yield()
{
	next = FindNext();
	push %eax
	push %ebx
	...
	mov %esp, TCB[current].esp 
	mov TCV[current].esp, %esp
	...
	push %ebx
	push %eax
}

2. 内核级线程的切换

在这里插入图片描述

  1. 中断进入,利用int指令或其他硬件中断的中断处理入口,核心工作是记录当前程序在用户态执行时的信息,如当前的使用的用户栈、当前程序执行位置、当前执行的现场信息等;
  2. 调用schedule()引起TCB的切换,将当前线程的状态修改为阻塞,添加到一个等待队列链表上,schedule()函数从就绪队列中选出下一个要执行线程的TCB,将指针指向它;
  3. 完成内核栈的切换,其实就是ESP寄存器值的切换;
  4. 中断返回,将切换后的内核栈中的用户态程序执行现场恢复出来;
  5. 用户栈的切换,将CS:EIP寄存器设置为当前用户程序执行地址,将SS:ESP寄存器设置为当前用户栈地址。

3. 思考

    操作系统的故事都是围绕多进程视图展开的,理解了进程、线程,就理解了操作系统的核心,掌握操作系统最根本的视图,才能在脑海里构建庞大的操作系统的具体图像。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值