18.1引言
在多线程(multithreaded,MT)出现之前,电脑程序的运行由一个执行序列组成。多线程对某些任务来说是最理想的。这些任务有以下特点:它们本质上就是异步的,需要多个并发事务,各个事务的运行顺序可以是不确定的、随机的、不可预测的。这样的编程任务可以被分成多个执行流,每个流都有一个要完成的目标。根据应用的不同,这些子任务可能都要计算出一个中间结果,用于合并得到最后的结果。运算密集型任务一般都比较容易分割为多个子任务。
由于顺序执行的程序只有一个线程在运行,它要保证做多个任务,并且不会有某个任务占用太多时间。执行多任务的顺序执行的程序一般程序控制流程都很复杂,难以理解。
使用多线程编程和一个共享的数据结构比如Queue,这种程序任务可以用几个功能单一的线程来组织。
18.2线程和进程
进程
进程是程序的一次执行。每个进程都有自己的地址空间、内存、数据栈及其他记录其运行轨迹的辅助数据。进程都有自己的内存空间、数据栈等,所以只能使用进程间通讯(interprocess communication,IPC),而不能直接共享信息。
线程
线程跟进程类似,不同的是,所有的线程运行在同一个进程中,共享相同的运行环境。一个进程的各个线程之间共享一片数据空间,所以线程之间可以比进程之间更方便地共享数据以及相互通讯。但是也有副作用,就是同一片数据,在多个线程访问顺序不同时,可能导致数据不一致问题,当然这是可以解决的。
18.3Python、线程和全局解释器锁
1、全局解释器锁(GIL)
Python代码的执行由Python虚拟机(也称解释器主循环)控制。在一个主循环中,只有一个线程在执行,与单核CPU类似,虽然Python解释器可以运行“多个”线程,但是在任意时刻,只有一个线程在解释器中运行。
以上原理由全局解释器锁(GIL)控制,保证同一时刻只有一个线程在运行。在多线程环境中,Python虚拟机按以下方式执行。
1)设置GIL
2)切换到一个线程去运行
3)运行:
a.指定数量自己码的指令,或者
b.线程主动让出控制(time.sleep())
4)把线程设置为睡眠状态
5)解锁GIL
6)再次重复以上所有步骤。
调用外部扩展(c程序等)时,GIL被锁定,直到这个函数结束为止。
2、退出线程
当一个线程结束计算,就退出了。线程可以调用thread.exit()之类的退出函数,也可以用python退出的标准方法,如sys.exit()或者抛出一个SystemExit异常等。不过不可以直接kill一个线程。
thread和threading两个模块进行进程、线程管理,作者建议不用thread,一个很明显的原因是:thread模块主线程退出时,所有其他线程没有被清除就退出了;threading就能确保所有“重要”的子线程都退出后,程序才会结束。
3、下面看一下单线程
#-*- coding:utf-8 -*- from time import sleep,ctime def loop0(): print ‘start loop0 at:‘,ctime() sleep(4) print ‘loop0 done at:‘,ctime() def loop1(): print ‘start loop1 at:‘,ctime() sleep(2) print ‘loop1 done at:‘,ctime() def main(): print ‘starting at:‘,ctime() loop0() loop1() print ‘all DONE at:‘,ctime() if __name__ == ‘__main__‘: main()
当第一个循环执行完之后才会继续执行第二个循环。
4、模块
python提供的几个多线程编程模块,包括thread、threading、Queue等。thread和threading允许我们创建和管理线程。thread提供了基本的线程和锁的支持,而threading提供了更高级别,功能更强的线程管理功能。Queue允许用户创建可以用于多个线程之间共享数据的队列数据结构。
作者再次强调不用thread而是用threading。
18.4Thread模块
两个例子
原文:http://www.cnblogs.com/batteryhp/p/5215170.html