字体
关灯
   存书签 书架管理 返回目录
    黄建功浑身一震。
    他猛地看向钱学敏,眼神中充满了惊疑。
    “你的意思是……”
    “你想想,”钱学敏的思路像一道闪电,划破了混乱的局面,“我们创建了任务A和任务B。但是,我们好像……忘了给它们各自指定一块独立的内存,作为它们自己的堆栈空间!”
    黄建功的脸色,瞬间变得惨白。
    他明白了。
    他彻底明白了!
    这是一个如此巨大,却又如此隐蔽的,思想上的钢印!
    在他们的潜意识里,在过去所有的编程经验里,一个程序,永远只有一个堆栈!
    整个系统,从头到尾,都共享着那块由系统在启动时分配好的,唯一的堆栈内存。
    所以,当他们设计“天枢”内核时,尽管他们天才般地想到了要为每个任务保存寄存器、程序计数器等“上下文”。
    但他们,却完完全全,彻彻底底地,忽略了最重要的一样东西!
    堆栈!
    每个任务,都应该有自己独立的,互不干扰的堆栈空间!
    而他们做了什么?
    他们让任务A和任务B,共用了同一个堆栈!
    黄建功的脑海中,瞬间浮现出灾难发生的全过程。
    1. 系统启动,分配了一个全局堆栈。
    2. 任务A开始运行,它调用了一些函数,在堆栈里压入了一些自己的数据,比如局部变量、返回地址。
    3. 任务A调用`system_yield()`,触发任务切换。
    4. “天枢”内核执行,将任务A的寄存器(包括那个指向公共堆栈的SP指针)保存到任务A的PCB里。
    5. 内核切换到任务B。
    6. 任务B开始运行。它也调用了函数,它也需要在堆栈里压入数据。但是!它使用的,是和任务A完全相同的那个堆栈!
    7. 于是,任务B的数据,就把任务A之前存放在堆栈里的数据,给覆盖了!冲掉了!
    灾难,在这一刻就已经注定。
    8. 任务B运行了一会儿,也调用了`system_yield()`。
    9. 内核再次切换,轮到任务A运行。
    10. 内核从任务A的PCB里,恢复了任务A所有的寄存器,包括那个SP指针。
    11. 任务A从上次暂停的地方继续执行。它准备从堆栈里弹出自己之前存入的返回地址,准备返回上一个函数。

关闭+畅/阅读=模式,看最新完整内容。本章未完,请点击下一页继续阅读》》
上一页 目录 下一页