多线程编程(一) 背景简介


  • 背景/简介
  • 线程和进程
  • 线程和Python
  • thread 模块
  • threading模块
  • 单线程和多线程对比
  • 多线程实践
  • 生产者-消费者问题和Queue/queue 模块
  • 线程的替代方案

在多线程(multithreaded , MT)编程出现之前,计算机程序的执行都是由单个步骤序列组成的,该序列在主机的cpu中按照同步顺序执行。无论是任务本身需要按照步骤执行,还是整个程序实际上包含多个子任务,都需要按照这种顺序方式执行。那么,假如这些子任务相互独立,没有因果关系(也就是说,各个子任务的结果不影响其他子任务的结果)这种做法是不是更符合逻辑呢?要是让这些独立的任务同时执行,会怎么样呢?很明显,这种并行处理的方式可以显著提高整个任务的性能。这就是多线程编程。

多线程编程对于具有如下编程特点的任务而言是非常理想的:本质上是异步的需要多个并发活动;每个活动的处理的顺序可能是 不确定的,或者说是随机的,不可预测的。这种编程任务可以被组织或划分为多个执行流,其中每个执行流都有个指定要完成的任务。根据应用的不同,这些子任务之间可能需要计算出中间结果,然后合并为最终的输出结果。

计算密集型的任务可以比较容易的划分为多个子任务,然后顺序执行或者按照多线程方式执行。而那种使用单线程处理多个外部输入源的任务就不那么简单了。如果不使用多线程,要实现这种编程任务,就需要为串行程序使用一个或多个计时器,并实现一个多路复用的方案。

一个串行程序需要从每个I/O终端通道来检查用户的输入;然而,有一点非常重要,程序在读取I/O终端通道时不能阻塞,因为用户的输入到达时间是不确定的,并且阻塞会妨碍其他I/O通道的处理。串行程序必须使用非阻塞I/O或者拥有计时器的阻塞I/O(以保证阻塞只是暂时的)。

由于串行程序只有唯一的执行线程,因此它必须兼顾需要执行的多个任务,确保其中的某个任务不会占用过多的时间,并对用户的响应时间进行合理的分配。这种任务类型的串行程序的使用,往往造成非常复杂的控制流,难以理解和维护。

使用多线程编程,以及类似queue的共享数据结构,这个编程任务可以规划成几个执行特定函数的线程。

  • UserRequsetThread: 负责读取客户端的输入,该输入可能来自I/O通道。程序将创建多个线程,每个客户端一个,客户端的请求将会被放入队列。
  • RequestProcessor: 该线程负责从队列中获取请求并进行处理,为第3个线程提供输出。
  • ReplyThread: 负责向用户输出,将结果传回给用户(如果是网络应用),或者把数据写到本地文件系统或数据库中。

使用多线程来规划这种编程任务可以降低程序的复杂性,使其实现更加清晰,高效,简洁。每个线程中的逻辑都不复杂,因为它只有一个要完成的特定作业。比如,UserRequsetThread的功能仅仅只是读取用户输入,然后把数据放到队列中,以提供其他的线程进行后续处理。每个线程都有其明确的作业,你只需要设计每一类线程去做一件事,并把这件事情做好就可以了。这种特定任务线程的使用类似汽车工厂的流水线。

你可能感兴趣的:(多线程编程(一) 背景简介)