有几个网友私下问我一些有关线程的事情。过节写个东西上来大家交流。
思维误区1,自己新建的THREAD是线程,自己的主程序不是线程. 很多人在多线程编程没有把主线程也当作线程。其实主线程也是线程。看起来是废话,这个话确实很重要,这个就意味着,在DELPHI中,不光你开的线程,还有你的主线程所有的内存分配也是串的,进锁排队的。主线程和线程的区别
A.一般来说主线程的优先级高了点。(当然你也可以自己设置)
B.主线程在WIN下是处理APPLICATION的消息。
其他基本与你自建线程无区别。
所以这一点还可以点破小白问题,比如主线程不能进锁。其实主线程也要进锁的。关键是主线程不能挂起死等。挂起死等就用户界面卡了或者假死了。所以要进代码一边等,一边切换到其他任务。
思维误区2.线程和面向对象。
C的时候写线程反而很简单。因为C不是面向对象的。 撸代码的时候非常清楚什么在线程,什么在主线程,因为撸代码思维和机器表现一致。但是DELPHI是面向对象的。经常老会问自己类似这样的问题:这个对象在主线程还是在线程。这个OO中毒太深了,这个问题我也问过。其实DELPHI也不是绝对的面向对象,只是面向对象的封装而已,其本质还是流式代码跟C没区别,也就是跟OO没有半毛关系。
那问 这个对象在线程跑还是在主线程跑? 我只能说,所有对象都在内存,至于你哪里跑要看你的线程走了多少代码。比如
TAAAA= CLASS;
Public
procedure A;
procedure B;
procedure C;
(假设Procedure A,B,C相互没有资源冲突和相互调用)
APP代码你调用了Procedure A. 建了一个线程,线程调用Procedure B, 线程结束。
主线程跑了Procedure A, 自己建的线程跑了Procedure B. 但是他们都属于类TAAAA。
所以思维要改回来,线程跟面向对象没有半毛钱关系。不要用面向对象的思维去设计你的线程。这样你就知道你的锁该放在哪里了。
思维误区3. 锁和无锁
很多编程书里把锁讲成如厕(群里我把这个比喻成偷人,因为如厕不够污,记不住,偷人够污,容易记住。)。一个人进了厕所,其他人在门外面等着。锁就是门,人就是线程。这样的设置就是竞争机制,厕所少,人多啊。假如没有竞争机制,那当然不要锁了,每人发一个厕所,人人都幸福啊。编程中,比如固定的配置数据,你跑线程的时候每个线程配一个复本。那就不要锁了。
锁是影响你的程序效率的。犹如这边要尿急了,厕所里的人还没有出来,心里OS,TMD上个厕所真麻烦。 你要降低锁在程序里的开销。无非几个有因素:
A.锁本身的开销。(好比:上厕所里面的人出来,外面的人进去本身要时间的,这个就是锁的开销–我是乱比喻了,其实不是这样的,但是本质差不多,这样讲便于理解)。所以操作系统提供很多锁的资源和方式,所谓原子锁。其实也是锁。
B,线程等太久。
犹如上厕所等太久,多费劲啊。要解决也就2个方面,
B1,里面的人蹲太长时间了,憋死了。所以你要尽量使你的LOCK里面的任务减少。防止蹲太久.
B2,等的人太多。。排队排到大街上了。所以你要规划好你的资源。让资源分片—这个做法好比设了多个厕所。解决方案还有一个就是线程池。就是减少人。这个用如厕的比喻估计更加污。还是表达出来便于理解。“犹如,设几个人把所有人的大便都拉了。”
很多事,道理真的就这么简单。设计线程模型的时候别想多了就行。难就难在设计的时候自己容易想多,想着想着就无解了,那是自己给自己的坑啊。