
课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
我们在说起线程安全的时候一般都会提到锁的应用技术,而今天我们就通过案例分析来了解一下,自旋锁与互斥锁的应用注意事项。
自旋锁和互斥锁是多线程程序中的重要概念。它们被用来锁住一些共享资源,以防止并发访问这些共享数据时可能导致的数据不一致问题。但是它们的不同之处在哪里?我们应该在什么时候用自旋锁代替互斥锁?
理论分析
从理论上说,如果一个线程尝试加锁一个互斥锁的时候没有成功,因为互斥锁已经被锁住了,这个未获取锁的线程会休眠以使得其它线程可以马上运行。这个线程会一直休眠,直到持有锁的线程释放了互斥锁,休眠的线程才会被唤醒。如果一个线程尝试获得一个自旋锁的时候没有成功,该线程会一直尝试加锁直到成功获取锁。因此它不允许其它线程运行(当然,操作系统会在该线程所在的时间片用完时,强制切换到其它线程)。
存在的问题
互斥锁存在的问题是,线程的休眠和唤醒都是相当昂贵的操作,它们需要大量的CPU指令,因此需要花费一些时间。如果互斥量仅仅被锁住很短的一段时间,用来使线程休眠和唤醒线程的时间会比该线程睡眠的时间还长,甚至有可能比不断在自旋锁上轮训的时间还长。自旋锁的问题是,如果自旋锁被持有的时间过长,其它尝试获取自旋锁的线程会一直轮训自旋锁的状态,这将非常浪费CPU的执行时间,这时候该线程睡眠会是一个更好的选择。
解决方案
在单核/单CPU系统上使用自旋锁是没用的,因为当线程尝试获取自旋锁不成功的时候会一直尝试,这会一直占用CPU,其它线程不可能运行,因为其他线程不能运行,这个锁也就不会被解锁。换句话说,在单核/单CPU的系统上,自旋锁除了浪费时间没有一点好处。这时如果这个线程(记为A)可以休眠,其它线程可以立即运行,因为其它有可能解锁,那么线程A可能在唤醒后继续执行。
在多核/多CPU的系统上,特别是大量的线程只会短时间的持有锁的时候,在使线程睡眠和唤醒线程上浪费大量的时间,也许会显著降低程序的运行性能。使用自旋锁,线程可以充分利用调度程序分配的时间片(经常阻塞很短的时间,不用休眠,然后马上继续它们的工作了),以达到更高的处理能力和吞吐量。
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。更多内容请加danei0707学习了解。欢迎关注“达内在线”参与分销,赚更多好礼。