Python2:线程挂起和线程阻塞
本文参考博客什么是线程阻塞?为什么会出现线程阻塞?、线程和进程/阻塞和挂起。
(1)线程挂起:
①线程挂起简介:
线程挂起操作实际上就是线程进入非可执行状态下,在这个状态下CPU不会分给线程时间片,“线程挂起“用来暂停一个线程的执行,”线程挂起“后通过唤醒线程使之恢复运行。
挂起线程是为了避免资源(CPU分配线程时间片)的浪费。
②线程挂起的方法:
1)废弃的方法:
1.thread.suspend():
不释放线程暂用的资源,如用于将线程挂起,可能会使其它等待资源的线程死锁。
2.thread.resume():
用于释放suspend()造成的线程挂起,方法本身没问题,但不能独立于suspend()方法使用。
2)常用方法:
1.wait():
暂停执行,放弃已获得的锁,进入等待状态。
2.notify():
随机唤醒一个等待锁的线程。
3.notifyAll():
唤醒所有等待锁的线程,自行抢占CPU。
③线程挂起的原因:
1)终端用户的请求:
当终端用户在自己的程序运行期间发现有可疑问题时,希望暂停使自己的程序静止下来,这种静止状态称为“挂起状态”。
2)父进程的请求:
有时父进程希望挂起自己的某个子进程以便考察和修改子进程,或者协调各子进程间的活动。
3)负荷调节的需要:
当实时系统中的工作负荷较重已可能影响到对实时任务的控制时,可由系统把一些不重要的进程挂起,以保证系统能正常运行。
4)操作系统的需要:
操作系统有时希望挂起某些进程,以便检查运行中的资源使用情况或进行记账。
5)对换的需要:
为了缓和内存紧张的情况,将内存中处于阻塞状态的进程换至外存上。
(2)线程阻塞:
①线程阻塞简介:
阻塞状态是正在运行的线程遇到某个特殊情况,如延迟、挂起等,进入阻塞状态的线程让出CPU,并暂时停止自己的执行。
线程进入阻塞状态后一直等待,直到引起阻塞的原因被消除。线程又转入就绪状态,重新进入就绪队列排队。
②出现线程阻塞的原因:
1)睡眠状态:
当一个线程执行代码的时候调用了sleep方法后,线程处于睡眠状态,在睡眠时间内有其他线程需要执行时就会造成线程阻塞。
sleep方法被调用之后,该线程不会释放锁对象,CPU执行权还在自己手里,等睡眠时间一过,该线程就会进入就绪状态。
2)等待状态:
当一个线程正在运行时调用了wait方法,此时该线程需要交出CPU执行权交给另一个线程,该线程进入等待状态。
进入等待状态的线程不需要设置睡眠时间,但是需要执行notify方法或者notifyall方法来对其唤醒,被唤醒之后该线程也会进入就绪状态,但是进入就绪状态的该线程是没有执行权的,而睡眠状态的线程一旦苏醒就拥有执行权。
3)礼让状态:
当一个线程正在运行时调用了yield方法,该线程会将执行权礼让给同等级的线程或者比它高一级的线程优先执行,此时该线程有可能只执行了一部分而进入阻塞状态,但是该线程会随时可能又被分配到执行权。
4)自闭状态:
当一个线程正在运行时调用了join方法,此时该线程会进入阻塞状态,另一个线程会运行,直到运行结束后,原线程才会进入就绪状态。
5)suspend() 和 resume() :
已废除,两个方法配套使用,suspend() 是让线程进入阻塞状态,resume()用于恢复就绪状态。
(3)线程挂起和线程阻塞的区别:
挂起一般是主动的,由系统或程序发出,不释放CPU,可能释放内存,放在外存。
阻塞一般是被动的,在抢占资源中得不到资源,被动的挂起在内存,等待某种资源或信号量将它唤醒,释放CPU,但不释放内存。