讨论:unix-linux需要系统栈么?需要每个进程一系统栈
我觉得在内核不许抢占的前提下,可以所有进程共用一个系统栈,甚至不需要单独的系统栈也可以的(进程结构放到其它地方,内核与进程使用相同的栈)但是每个进程一个系统栈的好处是什么?安全?还是效率? 我觉得在内核不许抢占的前提下
但是2.6以后就加入了抢占了~ 内核不许抢占的前提下 我觉得这个就是一个时间复杂度和空间复杂度的问题:
如果每个进程一个系统栈,那么空间上会有损失,不过却能节约搜索的时间 堆栈需要搜索么?看不出搜索的时间的快慢啊 ……………………
不对……这个…………我再去读读内核先~ 在内核2.x 之前的话用i386 的TSS 来完成进程切换时倒可以不用单独的内核栈,但以后就没有用到TSS 了,在进程切换时在每个被剥夺的进程的内核栈上保存了CS 和EIP ,这样只用一个内核栈就无法完成切换了。
The key strike is the macro __switch_to() called in the schedule()! CS 和EIP 干吗一定要保存在系统栈上?
可以保存在全局进程结构里啊,切换时把新进程的CS 和EIP 和SP从恢复进程结构里到系统栈里,这个操作不就相当于切换了系统栈? 我的想法是:
如果只有一个系统栈的话,刚被选出的进程的CS 和EIP 保存在系统栈上,这时转到被选入的进程,当再次进程调度时,从栈上获得CS 和EIP ,由于栈具有顺序访问的特点,只能运行刚保存的CS 和EIP ,就不能实现转到其他进程上运行,这样怎么实现进程调度的随机访问呢? 系统栈是必须的,带运行级的CPU都是这样的。直接改变EIP寄存器的值?你想象以下自己是CPU的设计者,你如何才能保证改变前和改变后能连续运行?因为你做改变的操作也是通过EIP进行的阿。
栈是有访问顺序的,不能随机访问,所以要分开来。 我的想法是:
如果只有一个系统栈的话,刚被选出的进程的CS 和EIP 保存在系统栈上,这时转到被选入的进程,当再次进程调度时,从栈上获得CS 和EIP ,由于栈具有顺序访问的特点,只能运行刚保存的CS 和EIP ,就不能实现转到其他进程上运行,这样怎么实现进程调度的随机访问呢?
在内核不被抢占的前提下,内核执行完毕返回到用户进程时,系统栈恢复到进入内核时的状态,所以只要保证系统栈上的用户进程CS/EIP/SP是新进程的的,就可以了。在linux是采用切换系统栈的方法,我觉得还可以强行更改系统栈的用户进程CS/EIP/SP使其指向新的进程来达到这个目的
至于是否一定需要单独的系统栈,由于从系统调用和中断返回到用户进程都是ret/iret指令完成的,所以需要硬件支持,在386里TSS寄存器可以保存
新进程的CS/EIP/SP,内核在用户栈里运行返回,不会在用户栈里留下任何痕迹,返回前将TSS指向新的进程就可以转到新的用户栈了
呵呵,即便是硬件不支持,在内核返回到用户进程前,也可以在返回前强行将堆栈指针指向新进程的栈的恰当位置,不是也可以返回到新进程的栈的指令空间么?
在内核可以被抢占的情况下,如果把被抢占的内核副本看做是该副本所抢占的进程的一部分(该内核副本返回时自然又清空了内核占用用户栈的部分,下次调度该进程时就没有什么问题了),似乎也不需要系统栈
总之,不需要硬件的特别支持,就可以不用系统栈,无论内核可否被抢占。每个用户进程一个系统栈的原因可能是实现的方便,高效和安全性
胡思乱想了这么多,欢迎指正! :mrgreen: 在物理上是共用的,但在数据结构上是独立的,所以除了进程结构更复杂一点外并没有增加其它额外的系统开销,牺牲并不重要的空间来简化设计是值得的。在多处理器构架下这种策略的优点更为突出。
当然,这也并不是惟一的策略,也不见得是最优策略。现代操作系统的设计要求机制与策略的分离,为了实现进程机制,可以有多个策略,各有优缺点。 关于这个问题,偶似乎有地方向错了
系统栈和用户栈合一可以
但是系统栈除了保存SS/SP/CS/IP外,还保存诸如内核局部变量参数等调用桢
不是简单的修改为期望进程的对应值那么容易,因为每个进程的内核上下文在进程切出时都保留在堆栈中,并不是不留下痕迹,所以每个用户进程一个系统栈(或者与用户栈合二为一)是必要的
:mrgreen:
页:
[1]