一、contextswitch的概念
contextswitch(上下文切换)是指操作系统暂停当前正在执行的进程,保存该进程的状态(上下文),并将CPU执行的状态切换到另一个就绪进程上,恢复该进程的状态,使其继续执行。
在单核CPU的情况下,CPU的时间片被划分成若干个时间片,每个时间片都由一个进程占用,进程执行完或者被唤醒后,就进行contextswitch。
在多核CPU的情况下,多个进程同时被处理,每个核心上的进程都有自己的时间片,所以contextswitch的操作会在多个核心之间进行。
二、contextswitch的过程
contextswitch的过程大概可以分为以下几个步骤:
1、当前进程被暂停。
2、内核中将当前进程的上下文(CPU状态、寄存器信息等)保存到进程控制块(PCB)中。
3、进程调度器选取下一个就绪进程。
4、内核中将下一个进程的上下文从进程控制块中恢复,设置为CPU的当前上下文。
5、新进程开始执行。
三、contextswitch的作用
1、实现多任务:在多任务操作系统中,contextswitch提供了用于切换不同进程的机制,使得多个进程可以在CPU上交替执行,实现并行处理。
2、避免死锁:当某个进程发生死锁时,其它进程可以通过contextswitch切换到其它进程,在一定程度上避免了死锁的发生。
3、提升系统的响应性:contextswitch可以让不同的进程依次使用CPU,从而提高系统的并发程度,进而提升系统的响应速度。
四、contextswitch的代码实例
void contextswitch(task_struct *prev, task_struct *next) { /* 保存进程上下文 */ __asm__ __volatile__("pushl %%ebp\n\t" "movl %%esp,%[prev_sp]\n\t" "movl %[next_sp],%%esp\n\t" "cmpl $0,%[prev_pid]\n\t" "jne 1f\n\t" /* 第一次进入,跳转至label 1*/ "movl %[next_entry],%%eax\n\t" "jmp *%%eax\n\t" /* 跳转至下一个进程的代码段 */ "1:\tmovl %[prev_pid],%%eax\n\t" "movl $(prev_task_exit),%%ebx\n\t" "movl %%ebx,%%eax\n\t" "call *%%eax\n\t" /* 执行上一个进程的退出处理函数 */ "movl %[next_entry],%%eax\n\t" "jmp *%%eax\n\t" /* 跳转至下一个进程的代码段 */ : [prev_sp] "=m"(prev->cpu_context.sp), [prev_pid] "=m"(prev->pid), [next_sp] "=m"(next->cpu_context.sp), [next_entry] "=m"(next->cpu_context.pc) : : "%eax", "%ebx", "memory"); }
五、contextswitch的优化
contextswitch操作是系统开销较大的操作,部分操作系统在此方面进行了优化,例如:
1、采用多级反馈队列调度算法,调整优先级,使高优先级进程尽早执行,以减小contextswitch的开销。
2、在系统内核中使用协程(coroutine),协程之间的切换比进程、线程之间的切换更为轻量,从而减小了contextswitch的开销。
3、使用Fiber,Fiber是用户模式下的线程,一般不需要进行内核态与用户态的切换,因此contextswitch的开销可以显著降低。
原创文章,作者:QJMTP,如若转载,请注明出处:https://www.506064.com/n/333090.html