首页 > 代码库 > 多线程的思考

多线程的思考

很多时候,我们只关注实现,并没有真正搞清楚本质就开始找各种API,然后写完代码就完事……直到最后测试暴露出很多问题,实在抓破头皮debug得快发疯的时候,才真正开始考虑隐藏在后面的本质。我有时也是如此,这是很悲哀的。

 

就比如说多线程的编程,我总是理所当然地认为新开辟的线程里面如果有死循环,那么里面必须有sleep释放,否则其他线程将无法获取到资源。但是在Linux下,我看到了别人完全不需要sleep,每个线程却都能被调度获取到运行的资源,这让我大大地开始怀疑我之前所有的多线程编程都有问题!!这就是我没完全搞清楚多线程调度造成的结果!

 

认真研究了一下,才发现其实操作系统中,CPU竞争有很多种策略。Unix系统使用的是时间片算法,而Windows则属于抢占式的。引用了一下别人博客的内容:

在时间片算法中,所有的进程排成一个队列。操作系统按照他们的顺序,给每个进程分配一段时间,即该进程允许运行的时间。如果在 时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。调度程 序所要做的就是维护一张就绪进程列表,,当进程用完它的时间片后,它被移到队列的末尾。

所谓抢占式操作系统,就是说如果一个进程得到了 CPU 时间,除非它自己放弃使用 CPU ,否则将完全霸占 CPU 。因此可以看出,在抢 占式操作系统中,操作系统假设所有的进程都是“人品很好”的,会主动退出 CPU 。

@http://www.tuicool.com/articles/a6f2En

那么,linux线程中没有sleep照样会被释放也就可以解释了。

 

再继续看,发现还有一种使用sleep(0)的有趣用法。

Thread.Sleep(0)的作用,就是“触发操作系统立刻重新进行一次CPU竞争”。竞争的结果也许是当前线程仍然获得CPU控制权,也许会换成别的线程获得CPU控制权。这也是我们在大循环里面经常会写一句Thread.Sleep(0) ,因为这样就给了其他线程比如Paint线程获得CPU控制权的权力,这样界面就不会假死在那里。

 

同样,今后关于线程同步,加锁造成的死锁等问题,也很需要花时间去弄清楚里面比较本质的东西,才能放心写出ok的程序。

多线程的思考