多线程编程杂说2

多线程编程普及出现在90年以后,之前只有多核的cpu服务器才有这样的需要。多线程以其复杂化脆弱性著称,程序员大多避而不谈或只是简单的应用。线程保护的互斥锁被认为是导致延迟和性能下降的主因。

这主要有两方面的原因,第一大部分应用只需要一个线程进行处理有着强烈的排他性和连贯性,第二很少有用户应用是大规模并发的即使有大规模也是短时间,可以使用单线程排队的方式也可以完美的解决。这样绝大部的应用被拆成分进程方式的分布式和单线程的方式两大块,多线程编程就此没落。多线程的方式有其不可替代的优势,其比分布式在通信方面的开销要非常小,比单线程方式又充分发挥服务器性能。好的多线程是能够平衡的使用服务器cpu资源,数据对cpu来说的透明的,按系统的cpu论片时间平均使用。多线程编程的难点是对数据的保护,划分的不好或者不恰当都会导致性能瓶颈。这要求对应用有着非常充分的理解。数据分为全局,线程内部,长量,变量等等。每种数据按逻辑应用的不同分别加以保护。例如线程相关的变量,只在某个线程使用的变量,可以不用加以保护。就现在编程语言来说还没有非常合适多线程编程的语言,例如线程数据就没有明显的区分,如被其他的线程误用也不会有编译错误的提示,调试也很困难。

当我们越来越依赖编译器和语言来解决基础错误的时候,多线程编程对工程师的要求可谓颇高。但其中还是有些规律和经验可以使用。

例如对mutex锁的应用可以把锁排列优先级,有1,2,3 三个互斥锁,在嵌套使用的时候必须按1,2,3的次序使用。当第二个线程使用2,3时就会等待第一线程释放第2个锁。如何第一线程使用顺序是1,2第二个线程使用是2,1很大的可能会造成第一个线程拿到了锁1等待锁2,而第二线程拿到了锁2等待锁1。两个线程就死锁了。

再举例说我们会把程序划分成很多的函数,重复使用函数使代码看起来更加的整洁,但在多线程编程中这点非常可怕。如果调用了很多层后,每一层的数据访问又分别加锁就很容易造成互斥锁的嵌套。所以多线程编程中对函数层次的使用是扁平化的最多不过两三层,把数据保护的部分尽量控制在一层之内。每次调用都有明确底层是否有互斥锁,如果已经使用那么上层就不能再使用。这点来说和对象编程语言重复使用函数追求有着严重的冲图,很多时候我不得不把比较分散的几个函数加锁的数据访问部分提取出来,再统一加一个锁以提高效率。

 

你可能感兴趣的:(多线程编程杂说2)