谈到为什么需要多线程编程,可能需要从并发这个概念的历史来说起。
在很久以前,计算机并没有操作系统,同一个时刻他们只能执行一个单独的程序,而且这些程序直接访问所有的计算机资源。在计算机刚面世的那个年代,程序的这种处理方式其实并没有什么不对。但是随着计算机以及软件的快速发展,操作系统以及多核处理器的诞生,这使得同一时刻只处理一个任务让计算机的效率变得很低,并且不能充分发挥计算机的能力,达到充分利用计算机资源的效果。所以同时执行多个程序就成为了必然。那么计算机同时执行多个程序会有那些优势呢?
- 资源的利用:程序有时候需要等待外部的操作,比如输入和输出,并且在等待的过程中不能做任何有价值的工作。在程序等待的过程中让另外的程序运行会提高效率。
- 公平竞争:多个用户和程序对系统资源拥有平等的权利。让它们通过更好的时间片方式来共享计算机,这要比结束一个程序后再开始下一个程序更可取。
- 方便处理:写多个程序并且让每个程序单独处理任务然后进行必要的协调要比写一个单独的程序来处理所有的任务更容易且更让人满意。
为了充分利用系统资源,让多个程序在同时运行的过程中公平竞争资源,充分利用计算机的处理能力,这有力的促进了进程以及线程的发展。线程允许程序控制流中的多个数据流同时存在于同一个进程中。他们共享进程范围内的内存以及文件句柄等资源,但是每个线程有它自己的程序计数器、栈、局部变量。线程也为多处理器系统中并行的使用硬件提供了一个自然而然的分解;同一个程序的多个线程可以在多个CPU的情况下同时调度。
线程的简单介绍
线程也成为轻量级的进程,并且现在大多数的操作系统都将线程作为基本的调度单元。在没有显示调度的情况下,每个线程都是同时且异步执行。由于线程共享他们所在的进程的内存地址空间,在执行过程中所有的线程都可能访问相同的变量并在同一个堆上分配对象,这相对于进程间通信(inner-process)机制来说,它提供了更细粒度的数据共享机制。但是对于共享的数据如果没有显示的同步机制,一个线程可能修改另一个线程正在修改的变量,这将会导致意外的结果。
因为程序调度的基本单元是线程,一个单线程应用程序一次只能运行在一个处理器上。在双处理器系统中,一个单线程程序,放弃了其中一半的空闲CPU资源;在拥有100个处理器的系统中,这个单线程程序放弃了99%的资源。从另一方面来看,拥有多个活跃线程的程序可以同时在多处理器上运行。早设计良好的情况下,多线程程序通过更有效的利用空闲处理器资源,来提高吞吐量。
使用多线程也可以帮助我们在单处理器系统中实现更佳的吞吐量。如果一个程序是单线程的 ,这个处理器在等待一个同步I/O操作完成的时候,仍然是空闲的。在一个多线程程序中,当一个线程等待I/O结束的同时,另一个线程也可以运行,这样就使得应用程序在遇到I/O阻塞时仍然有进展。
相对于需要同时管理多种类型的任务,一个顺序处理相同类型任务的程序,写起来简单,更少出错,也更容易测试。在模拟情况下,为每一个类型的任务分配一个线程,或者为每一个元素分配一个线程,提供理想上的顺序,并且这样做可以把域逻辑与时序调度的细节隔绝开来,进行相互交替的操作,进行异步I/O,以及等待资源。一个复杂,异步的流程可以被分解为一系列更简单的同步流程,他们中每一个在相互独立的线程中运行,只有在特定的同步点才进行彼此间的交互。
多线程编程给我们带来了很多的优势,它让我们的应用能够同时做多件事情,但是在开发多线程应用时,我们需要注意的问题有很多,比如线程同步、线程间通信、线程死锁等等,后续我们会将更深入的讨论这些问题,一起学起,一起成长。