并发和线程是相互纠缠的问题,选择先学哪个也许很难。本文将先讲讲并发,它将为后面学习线程准备一些该先了解一下的知识。
术语
并发
并发是这样一个状态——许多Task同时启动。当并发被实现得恰恰当当时,它可能被认为是“harmony”。而实现得糟糕时,就成了”chaos“。
在大部分情况中,所说的Task指的都是线程。然而,Task也可以是进程或者纤程。
两者之间的分界通常很清楚,而使用合适的技术才是关键
Contention
确切的说何为Contention?Contention就是当多于一个Task尝试着同时访问那独独一个资源时的情况。
如果你是在大家庭长大的孩子,可能这个比喻能很好的解释它意思。想想家里要是有六个小孩,妈妈把一块小匹萨放在桌上作为晚餐,会发生什么样的情况。那就是Contention的含义。
无论何时,只要多个并发的Task需要用读/写的方式访问数据,对数据的访问都必须得到控制从而保护它的完整性。如果访问没有得到控制,两个或者更多的Task可能会“崩溃”。当其中的一个尝试着要读取变量时,另外一个可能要同时对它进行写入。如果一个Task正在写,而另外一个正在读,那个读的Task可能读取了部分写入的数据从而获得的是损坏了的数据。一般这样的操作是不会立即导致异常的,而只会在这之后给程序带来错误。
Contention问题经常是在低流量的Implementation中不会出现,因而在开发阶段经常是一点问题都没有。所以在开发的阶段应该采用合适的技术和压力测试。否则就有一些像玩Russian Roulette,问题在开发阶段仅仅是偶尔出现但是在部署阶段变成了频繁出现。
资源保护
资源保护是用来阻止由Contention带来的问题的解决办法。资源保护的目的是一次仅让一个Task访问指定的资源。
解决Contention
无论何时,只要多个线程需要以读/写的方式访问数据,对数据的访问都必须得到控制从而保护它的完整性。这可能对于不熟悉线程操作的程序员来说intimidating。然而,大部分服务器不需要全局数据。这些程序一般在启动过程中初始化之后只需要读取数据。只要没有写操作,线程可以没有任何副作用的读
取全局数据。
下面讲的是解决Contention最常用的办法。
只读
最简单的办法是只读。任何简单类型(整数,字符串,内存)以只读的方式访问不需要任何保护。这也可以扩展到诸如TLists等许多复杂类型。只要它们不以读/写方式访问任何全局或者成员变量,类型在只读方式时都是安全的。
此外,资源可以在任何可能的读操作之前被改写。这允许了在读取它的Task启动之前,先初始化资源。
上一页12345下一页