线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。线程是程序级别的概念,一个程序可以有多个线程同时执行(子功能可以同时执行)。
线程分为程序主线程和子线程两种。任何进程都会自动启动唯一的主线程。主线程可以随意启动多个子线程。
一个Python脚本程序运行,Python虚拟机就启动了一个进程,同时启动一个主线程mainTread。
我们可以在一个python程序中创建多个子线程,每个子线程启动由程序指令控制。
Python通过两个标准库_thread和threading提供对线程的支持。
_thread提供了低级别的、原始的线程以及一个简单的锁。
以下为基本代码实现
import _thread #引入线程模块
import time
#定义线程函数:就是用来封装子线程执行的代码
def workFunction(threadName,delay):
print("线程"+threadName+"启动执行:")
time.sleep(1)
print("线程代码执行完成,子线程退出销毁")
pass
if __name__=="__main__":
#启动多个子线程
_thread.start_new_thread(workFunction, ('线程1',0.001)) #启动第一个子线程
_thread.start_new_thread(workFunction, ('线程2', 0.001)) #启动第一个子线程
while True:
print("主线程在running!!!!!")
time.sleep(0.1)
pass
threading 模块提供的方法:
run(): 用以表示线程活动的方法。
start():启动线程活动。
join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
以下为基本代码实现
import threading
import time
#定义煮水的线程
class BoilWatter(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
pass
def run(self):
print("开始煮水。")
time.sleep(10) #wait状态
print("煮水结束。")
pass
pass
#定义洗杯子的线程类
class WashCup(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
pass
def run(self):#不能带参数
for i in range(3):
print("洗第{0}个杯子".format(i+1))
time.sleep(3)
print("洗完第{0}个杯子".format(i+1))
pass
print()
pass
pass
if __name__=="__main__":
thread1=BoilWatter()
thread2 = WashCup()
thread1.start()
thread2.start()
多个线程在执行的时候为随机模式,有哪个线程占用CPU我们无法进行控制。但如果需要强行要求某一个线程执行完毕后再执行另一个线程,这种情况就需要使用线程同步技术。
Python的线程同步技术有两种比较典型的解决方案:锁同步 和 条件变量同步。
锁:将一个线程的run()方法进行锁定,在全部执行完毕后在解除锁定。这样其他线程在执行的时候需要等待解除锁定后方可继续执行(锁定和解锁必须成对出现,否则出现“死锁”)。
线程锁对象 = Threading.Lock()
线程锁对象.acquire() # 锁定
线程锁对象.release() # 解除锁定
import threading
import time
#定义抢票线程类
lock = threading.Lock() # 共享内存锁
class OrderTicket(threading.Thread):
tickets=1000
def __init__(self,name):
threading.Thread.__init__(self)
self.__name=name
pass
def run(self):
#lock.acquire()
while OrderTicket.tickets>0:
#time.sleep(0.001)
lock.acquire() #同步导致并发效率降低
if OrderTicket.tickets>0:
OrderTicket.tickets-=1
print("{0}抢到一张票,剩下{1}".format(self.__name,OrderTicket.tickets))
lock.release()
time.sleep(0.01)
pass
pass
pass
Python提供的Condition对象提供了对复杂线程同步问题的支持。
Condition被称为条件变量,除了提供与Lock类似的 acquire和release方法外,还提供了wait和notify方法。
条件变量同步工作原理:线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则 wait;如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。不断的重复 这一过程,从而解决复杂的同步问题。
import threading
import time
import random
#使用共享区模拟变量
count=0
#创建条件对象
condition=threading.Condition()
class Producer(threading.Thread):
def __init__(self,threadName):
threading.Thread.__init__(self)
self.threadName=threadName
pass
def run(self):
global count
while True:
if condition.acquire():
if count>=10:
print('共享区已满,生产者Producer线程进入阻塞Block状态,停止放入!')
condition.wait()
else:
count+=1
msg=time.ctime()+' '+self.threadName+'生产了1件商品放入共享区,共享区总计商品个数:',count
print(msg)
condition.notify()
condition.release()
time.sleep(random.randrange(10)/5)
pass
pass