创建线程 #
由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程。
Python的标准库提供了两个模块:_thread和threading,_thread是低级模块,threading是高级模块,对_thread进行了封装。绝大多数情况下,我们只需要使用threading这个高级模块。
创建线程的语法:
t = threading.Thread()
常用参数:
name:线程名,如果不起名字Python就自动给线程命名为Thread-1,Thread-2
target:线程执行的函数
args:传递给线程函数的参数,必须是个tuple元组类型
import time, threading
def printCount(sec):
print('线程 %s 正在运行...' % threading.current_thread().name)
n = 0
while n < 5:
n += 1
print('线程 %s >>> %s' % (threading.current_thread().name,n))
# 推迟线程的调用sec秒
time.sleep(sec)
print('线程 %s 结束运行...' % threading.current_thread().name)
t1 = threading.Thread(name='printConut1',target=printCount,args=(1,))
t2 = threading.Thread(name='printConut2',target=printCount,args=(3,))
t1.start()
t2.start()
threading #
- threading.currentThread(): 返回当前的线程变量。
- threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
- threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
Thread #
- **run():**用以表示线程活动的方法。
- **start():**启动线程活动。
- join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
- isAlive(): 返回线程是否活动的。
- getName(): 返回线程名。
- setName(): 设置线程名。
Lock #
如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步。
import threading
count = 0
# 每次调用先+8、后-8,结果应该是0
def addCount():
global count
count = count + 8
count = count - 8
def threadRun():
for i in range(2000000):
addCount()
t1 = threading.Thread(target=threadRun)
t2 = threading.Thread(target=threadRun)
t1.start()
t2.start()
t1.join()
t2.join()
#此时的count不是0
print(count)
使用同步锁,由于锁只有一个,无论多少线程,同一时刻最多只有一个线程持有该锁,所以,不会造成修改的冲突。创建一个锁就是通过threading.Lock()来实现
当多个线程同时执行lock.acquire()时,只有一个线程能成功地获取锁,然后继续执行代码,其他线程就继续等待直到获得锁为止。
获得锁的线程用完后一定要释放锁,否则那些苦苦等待锁的线程将永远等待下去,成为死线程。所以我们用try...finally来确保锁一定会被释放。
threading.Lock().acquire():获得锁
threading.Lock().release():释放锁
import threading
lock = threading.Lock()
count = 0
# 每次调用先+8、后-8,结果应该是0
def addCount():
#加锁
lock.acquire()
global count
try:
count = count + 8
count = count - 8
finally:
#释放锁
lock.release()
def threadRun():
for i in range(2000000):
addCount()
t1 = threading.Thread(target=threadRun)
t2 = threading.Thread(target=threadRun)
t1.start()
t2.start()
t1.join()
t2.join()
#此时的count不是0
print(count)