当前位置:  技术问答>linux和unix

关于操作系统进程调度

    来源: 互联网  发布时间:2016-05-19

    本文导语:  操作系统的主要功能之一是处理机分配,就是将某个进程分配到处理上运行,我的疑问是操作系统是在处理机上运行的,操作系统如何将进程分配到处理机上的啊,操作系统将进程分配到处理机上后,操作系统是啥状...

操作系统的主要功能之一是处理机分配,就是将某个进程分配到处理上运行,我的疑问是操作系统是在处理机上运行的,操作系统如何将进程分配到处理机上的啊,操作系统将进程分配到处理机上后,操作系统是啥状态,操作系统是阻塞?(单处理机系统)

|
 进程切换过程

从一个进程的上下文切换到另一个进程的上下文,因为其发生频率很高,所以通常都是调度器效率高低的关键。在Linux中,这一功能是以一段经典的汇编代码实现的,此处就着力描述这段代码。

这段名为switch_to()的代码段在schedule()过程中调用,以一个宏实现:

/* 节选自[include/asm-i386/system.h] */
#define switch_to(prev,next,last) do {
asm volatile("pushl %%esint"
     "pushl %%edint"
     "pushl %%ebpnt" 保存esi、edi、ebp寄存器
     "movl %%esp,%0nt" esp保存到prev->thread.esp中
     "movl %3,%%espnt" 从next->thread.esp恢复esp
     "movl $1f,%1nt" 在prev->thread.eip中保存"1:"的跳转地址,当prev被再次切换到的时候将从那里开始执行
     "pushl %4nt" 在栈上保存next->thread.eip,__switch_to()返回时将转到那里执行,即进入next进程的上下文
     "jmp __switch_ton" 跳转到__switch_to(),进一步处理(见下)
     "1:t"
     "popl %%ebpnt"
     "popl %%edint"
     "popl %%esint" 先恢复上次被切换走时保存的寄存器值,再从switch_to()中返回。
     :"=m" (prev->thread.esp), %0
                      "=m" (prev->thread.eip),%1
      "=b" (last) ebx,因为进程切换后,恢复的栈上的prev信息不是刚被切换走的进程描述符,因此此处使用ebx寄存器传递该值给prev
     :"m" (next->thread.esp), %3
                       "m" (next->thread.eip), %4
        "a" (prev), "d" (next), eax,edx
        "b" (prev)); ebx
} while (0)
 


进程切换过程可以分成两个阶段,上面这段汇编代码可以看作第一阶段,它保存一些关键的寄存器,并在栈上设置好跳转到新进程的地址。第二阶段在switch_to()中启动,实现在__switch_to()函数中,主要用于保存和更新不是非常关键的一些寄存器(以及IO操作许可权映射表ioperm)的值:

unlazy_fpu(),如果老进程在task_struct的flags中设置了PF_USEDFPU位,表明它使用了FPU,unlazy_fpu()就会将FPU内容保存在task_struct::thread中; 
用新进程的esp0(task_struct::thread中)更新init_tss中相应位置的esp0; 
在老进程的task_struct::thread中保存当前的fs和gs寄存器,然后从新进程的task_struct::thread中恢复fs和gs寄存器; 
从新进程的task_struct::thread中恢复六个调试寄存器的值; 
用next中的ioperm更新init_tss中的相应内容 
switch_to()函数正常返回,栈上的返回地址是新进程的task_struct::thread::eip,即新进程上一次被挂起时设置的继续运行的位置(上一次执行switch_to()时的标号"1:"位置)。至此转入新进程的上下文中运行。


|
进程A在运行的时候,OS并不是无事可做,在那闲着的!A需要的内存空间,文件读写都是通过系统调用

,由OS在底层来实现的,别忘了操作系统的五大管理功能,A是不能直接越过OS内核直接读写硬件的!

针对楼主的问题,如果当前没有用户进程在运行,默认会执行系统的一个空闲进程,通常叫Idle进程,这个进程

通常什么都不做,仅仅是维护一个计数器而已...

|
并不只是时钟中断会发生调度,任何一个系统调用进入了内核态就可能会发生调度了,比如write, read

|
如果没有任何系统调用,OS什么也不做,直到时间片用来,OS重新调度

|

有内存与外存就绪状态

|
进程A运行完是以什么为标志呢?main()函数返回了,这也就到系统内核去了。所以OS又得到了控制权, 可以重新找一个新的就绪程序运行。

|
进入内存进入就绪状态
得到处理机进入运行状态

|
OS为了标识进程,定义了一个叫 进程控制块 的数据结构,通常简称为PCB或TCB,在linux 0.11里面的定义如下:
2.6版本的内核里,这个结构的定义很长,就不贴了,有兴趣自己下载内核源码看吧。

struct task_struct {
/* these are hardcoded - don't touch */
long state; /* -1 unrunnable, 0 runnable, >0 stopped */
long counter;
long priority;
long signal;
struct sigaction sigaction[32];
long blocked; /* bitmap of masked signals */
/* various fields */
int exit_code;
unsigned long start_code,end_code,end_data,brk,start_stack;
long pid,father,pgrp,session,leader;
unsigned short uid,euid,suid;
unsigned short gid,egid,sgid;
long alarm;
long utime,stime,cutime,cstime,start_time;
unsigned short used_math;
/* file system info */
int tty; /* -1 if no tty, so it must be signed */
unsigned short umask;
struct m_inode * pwd;
struct m_inode * root;
struct m_inode * executable;
unsigned long close_on_exec;
struct file * filp[NR_OPEN];
/* ldt for this task 0 - zero 1 - cs 2 - ds&ss */
struct desc_struct ldt[3];
/* tss for this task */
struct tss_struct tss;
};

然后还有几个list的列表,里面分别保存着当前处于不同状态的进程。当发生进程切换的时候(由多个可能的条

件触发),会首先修改当前这个进程的PCB内部的某些数据,然后将它丢到相应的list里面去,比如挂起队列等。

然后会搜索当前处于就绪状态的队列,找到队列里面处于第一个结点的进程,然后运行它...

大概的过程就是这样,其中内部的例如寄存器的压栈和恢复,内存区域的设置等细节就不说,楼主自己看书吧...

|


楼主的意思是进程的切换是由操作系统(os)做的,假设进程A被调到到处理机上运行,进程A在处理机上运行时,os在做什么?

|
我的理解是:程序并不是连续执行的, 在每个时钟中断后执行中断代码, 然后完成操作系统的调度功能

还请高手传道 

|
。。没懂楼主说啥

|
是先进入就绪态才有可能被重新装载内存。


    
 
 

您可能感兴趣的文章:

  • 请问操作系统中任务调度主要有哪些策略,LINUX用哪种啊??实时操作系统又有哪些任务调度哪些策略啊??
  • .net/c#/asp.net iis7站长之家
  • java实现操作系统的短进程作业调度示例分享
  • 调用fork操作后,子进程有返回,父进程挂死,什么原因?
  • 操作系统为进程(程序)提供服务的疑问
  • 子进程如何操作父进程中的变量
  • 请问大虾们,同一串口能否被多个进程同时操作?
  • UNIX 操作系统中进程之间调用的通信方式
  • LINUX操作系统 的进程管理。基础的。 求救!~!
  • 执行一个main函数程序时,unix操作系统调用什么创建进程?fork?newproc?
  • 进程内核栈和操作系统内核栈的关系
  • 在有无操作系统的时候,如何判断一个进程的结束啊?
  • 每个线程有自己私有的堆栈,其实这些堆栈的资源是操作系统分配给进程的,这种说法对吗?
  • 如何查询SEMOP函数,最后一次操作成功的进程
  • 文件操作 多个进程打开文件 不加锁 情况如何
  • Linux中多个进程同时操作一个文件???
  • (100分求助)用内核线程对用户进程操作(大侠/虾们出手了)
  • HP-Unix操作系统, java进程, Swap空间不释放
  • UNIX下两个进程对一个文件操作
  • C#获取进程和对进程的操作
  • 如何实现操作不被其他进程打断?
  • Solaris下,如何在程序中实现关机操作?怎样取出线程和进程数?谢谢!
  • 如何在Linux下用驱动程序切出200MB内存,不让操作系统使用,给某一进程独享
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • mount命令(linux操作系统)挂载卸载文件系统(cifs,光驱,nfs等)方法介绍
  • 谁有操作系统PV操作的例子???谁有操作系统PV操作的例子???谢谢!!
  • linux哪个版本好?linux操作系统版本详细介绍及选择方案推荐
  • windows 系统是否是多用户操作系统,如何理解“多用户操作系统”的“多用户”?
  • Linux下u盘文件系统相关操作
  • 正在学操作系统原理,做操作系统方面的实验用那种工具较好?
  • windows7操作系统介绍及各种使用技巧总结
  • 请问16位操作系统和32位操作系统的区别?
  • linux 操作系统下ps命令介绍
  • java执行操作系统命令的问题:如何判断多个操作系统?
  • Linux操作系统和Hurd操作系统
  • 怎样在装有红帽操作系统的机子进行格式化,重新装Windows操作系统?
  • 请问各位,我想学习linux,是装linux操作系统还是在虚拟机下装操作系统呢?那种好点啊
  • 可不可以这样认为!c语言是一道唯一指向操作系统的语言,精通了它,就了解了操作系统?
  • 已安装了Windows操作系统,还想安装Linux。却还想在开机选择操作系统时由Windows引导,请问如何操作。在线等待
  • windows操作系统做服务器,客户端是unix操作系统,如何配置unix才能上网
  • ARM系列开发板是不是一定要用LINUX操作系统。windows操作系统可以吗?
  • 在window 的操作系统里,应该有个软件可以实现,安装一个虚拟的linux操作系统
  • 32位操作系统和64位操作系统字符存贮的区别?急
  • 请问netware 是不是操作系统, 为什么csdn 的操作系统栏里面没有设置它的。
  • itron与rtlinux实时操作系统各自的优点与缺点。我现在有一个项目。想权衡综合考虑用那一个操作系统。
  • C++ Stacks(堆栈) 成员 操作:比较和分配堆栈
  • 什么样的操作最耗费服务器的IO操作?
  • C++ Strings(字符串) 成员 Operators:操作符,用于字符串比较和赋值
  • 请问命令行操作下怎么改Linux操作系统的日期和时间?
  • C++ I/O 成员 flags():操作flags
  • 基于linux操作系统之上操作LCD问题,急???
  • C++ I/O 成员 width():操作域宽度
  • 哪位大侠知道Linux里的有名管道传送数据快不快?有名管道操作的过程是否有读写硬盘的操作?
  • c#对象中两种copy操作:深拷贝(Deep Copy)与浅拷贝(Shallow Copy)
  • 如何在一个用户对application操作时防止别的用户对它操作?(好难啊)


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3