没有合适的资源?快使用搜索试试~ 我知道了~
Python函数式编程
资源推荐
资源详情
资源评论
Python
线程指南
本文介绍了 Python 对于线程的支持,包括“学会”多线程编程需要掌握的基础以及 Python 两个线程标准
库的完整介绍及使用示例。
注意:本文基于 Python2.4 完成,;如果看到不明白的词汇请记得百度谷歌或维基,whatever。
尊重作者的劳动,转载请注明作者及原文地址 >.<
1. 线程基础
1.1. 线程状态
线程有 5 种状态,状态转换的过程如下图所示:
1.2. 线程同步(锁)
多线程的优势在于可以同时运行多个任务(至少感觉起来是这样)。但是当线程需要共享数据时,可能存
在数据不同步的问题。考虑这样一种情况:一个列表里所有元素都是 0,线程"set"从后向前把所有元素
改成 1,而线程"print"负责从前往后读取列表并打印。那么,可能线程"set"开始改的时候,线
程"print"便来打印列表了,输出就成了一半 0 一半 1,这就是数据的不同步。为了避免这种情况,引入
了锁的概念。
锁有两种状态——锁定和未锁定。每当一个线程比如"set"要访问共享数据时,必须先获得锁定;如果已
经有别的线程比如"print"获得锁定了,那么就让线程"set"暂停,也就是同步阻塞;等到线程"print"访问
完毕,释放锁以后,再让线程"set"继续。经过这样的处理,打印列表时要么全部输出 0,要么全部输出
1,不会再出现一半 0 一半 1 的尴尬场面。
线程与锁的交互如下图所示:
1.3. 线程通信(条件变量)
然而还有另外一种尴尬的情况:列表并不是一开始就有的;而是通过线程"create"创建的。如果"set"或
者"print" 在"create"还没有运行的时候就访问列表,将会出现一个异常。使用锁可以解决这个问题,但
是"set"和"print"将需要一个无限循环——他们不知道"create"什么时候会运行,让"create"在运行后通
知"set"和"print"显然是一个更好的解决方案。于是,引入了条件变量。
条件变量允许线程比如"set"和"print"在条件不满足的时候(列表为 None 时)等待,等到条件满足的时
候(列表已经创建)发出一个通知,告诉"set" 和"print"条件已经有了,你们该起床干活了;然
后"set"和"print"才继续运行。
线程与条件变量的交互如下图所示:
1.4. 线程运行和阻塞的状态转换
最后看看线程运行和阻塞状态的转换。
阻塞有三种情况:
同步阻塞是指处于竞争锁定的状态,线程请求锁定时将进入这个状态,一旦成功获得锁定又恢复到运行状
态;
等待阻塞是指等待其他线程通知的状态,线程获得条件锁定后,调用“等待”将进入这个状态,一旦其他线
程发出通知,线程将进入同步阻塞状态,再次竞争条件锁定;
而其他阻塞是指调用 time.sleep()、anotherthread.join()或等待 IO 时的阻塞,这个状态下线程不会释
放已获得的锁定。
tips: 如果能理解这些内容,接下来的主题将是非常轻松的;并且,这些内容在大部分流行的编程语言里
都是一样的。(意思就是非看懂不可 >_< 嫌作者水平低找别人的教程也要看懂)
2. thread
Python 通过两个标准库 thread 和 threading 提供对线程的支持。thread 提供了低级别的、原始的线程
以及一个简单的锁。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# encoding: UTF-8
importthread
importtime
# 一个用于在线程中执行的函数
deffunc():
fori inrange(5):
print'func'
time.sleep(1)
# 结束当前线程
# 这个方法与 thread.exit_thread()等价
thread.exit() # 当 func 返回时,线程同样会结束
# 启动一个线程,线程立即开始运行
# 这个方法与 thread.start_new_thread()等价
# 第一个参数是方法,第二个参数是方法的参数
thread.start_new(func, ()) # 方法没有参数时需要传入空 tuple
# 创建一个锁(LockType,不能直接实例化)
# 这个方法与 thread.allocate_lock()等价
lock =thread.allocate()
# 判断锁是锁定状态还是释放状态
printlock.locked()
# 锁通常用于控制对共享资源的访问
40
count =0
# 获得锁,成功获得锁定后返回 True
# 可选的 timeout 参数不填时将一直阻塞直到获得锁定
# 否则超时后将返回 False
iflock.acquire():
count +=1
# 释放锁
lock.release()
# thread 模块提供的线程都将在主线程结束后同时结束
time.sleep(6)
thread 模块提供的其他方法:
thread.interrupt_main(): 在其他线程中终止主线程。
thread.get_ident(): 获得一个代表当前线程的魔法数字,常用于从一个字典中获得线程相关的数据。这
个数字本身没有任何含义,并且当线程结束后会被新线程复用。
thread 还提供了一个 ThreadLocal 类用于管理线程相关的数据,名为 thread._local,threading 中引
用了这个类。
由于 thread 提供的线程功能不多,无法在主线程结束后继续运行,不提供条件变量等等原因,一般不使
用 thread 模块,这里就不多介绍了。
3. threading
threading 基于 Java 的线程模型设计。锁(Lock)和条件变量(Condition)在 Java 中是对象的基本行
为(每一个对象都自带了锁和条件变量),而在 Python 中则是独立的对象。Python Thread 提供了
Java Thread 的行为的子集;没有优先级、线程组,线程也不能被停止、暂停、恢复、中断。Java
Thread 中的部分被 Python 实现了的静态方法在 threading 中以模块方法的形式提供。
threading 模块提供的常用方法:
threading.currentThread(): 返回当前的线程变量。
threading.enumerate(): 返回一个包含正在运行的线程的 list。正在运行指线程启动后、结束前,不包
括启动前和终止后的线程。
threading.activeCount(): 返回正在运行的线程数量,与 len(threading.enumerate())有相同的结果。
threading 模块提供的类:
Thread, Lock, Rlock, Condition, [Bounded]Semaphore, Event, Timer, local.
3.1. Thread
剩余63页未读,继续阅读
资源评论
不要说不
- 粉丝: 8
- 资源: 65
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功