线程状态的迁移

 线程状态的迁移_第1张图片


运行→就绪:
有时间片的线程在时间片用完的时候,被系统转为就绪状态并移到优先级队列的末尾;可被抢占的线程在出现一个更高优先级的可运行的线程时会被抢占,转为就绪状态。但是在这种情况下它不会被移到优先级队列的末尾;线程可以自己调用relinquish()函数自己放弃运行,转为就绪并移到优先级队列末尾。
就绪→运行:
当线程被调度运行的时候,其由就绪态转变为运行态。
运行→挂起:
线程可以将自己挂起。一个典型的例子就是sleep调用。但是挂起的线程不能够唤醒自己,就是sleep调用后也是由时间管理负责唤醒的。另外线程调用suspend()也可以将自己无条件挂起,这个挂起,只能由其他线程用 resum() 调用唤醒。这样的做法,典型的应用是在等待队列机制(wait_queue)中的实现。
就绪→挂起:
就绪状态下的线程可以被别的线程挂起。目前NGSA屏蔽了Nucleus的这种功能,即一个线程不能随随便便将其他线程挂起。
挂起→就绪:
当挂起的线程被唤醒后,线程即转为就绪状态。线程唤醒后会被放到相应优先级队列的尾部,等待系统调度。
运行 / 就绪 / 挂起→终止:
当前线程可以调用terminate_task()函数终止处于其他状态的别的线程;在Nucleus中,当前线程也可以终止自己,但在NGSA中,我们不推荐这么做。即使终止其他线程,我们也必需保证线程获取的资源在终止操作之前都已经正确释放,比如打开的文件已经关闭,申请的内存空间已经释放,持有的锁已经解开,等等。所以,对于终止线程的操作,我们要特别谨慎,在代码审查上,对于这样的操作要严格仔细检查,确保不会出现资源泄漏等问题。
终止一个线程,我们一般是为了删除它,线程终止之后就不能再得到调度了。要删除一个线程前,必需确保它处于终止或完成状态。
运行→完成:
当前线程正常运行完毕以后,就返回TCC_Task_Shell函数,将自己置为完成态。线程处于完成态之后,就不会再进行调度了,这个时候可以使用delete_task()函数将之安全删除。

你可能感兴趣的:(linux内核)