python多线程
- 多线程
- threading库
- 常用方法
- thread类
- 继承thread类
- 全局变量的问题
- 不加线程锁
- 添加线程锁Lock(线程同步)
- queue线程安全队列
多线程
单线程(按序列并发执行)
执行
进程1
进程2
进程3
进程4
结束
多线程(并行同时执行)
执行
进程1
结束
进程2
进程3
进程4
threading库
常用方法
- currentThread() 返回当前的线程变量
- enumerate() 返回一个正在运行的线程list
- activeCount() 返回正在运行的吸纳从数量(类似len(enumerate))
thread类
查询定义的thread类中start、run等方法
thread类
- run() 线程活动的方法
- start() 启动线程
- join([time]) 阻塞调用线程直至线程的joiin()方法被调用终止
- isActive 是否执行
- getName() 但返回线程的名字
- setName() 设置线程的名字
例:单线程、多线程分别执行两个函数的过程
import threading,time
def coding():
for t in range(0,2):
print('正在写python!')
run_count()
time.sleep(1)#延迟1s
def game():
for t in range(0,2):
print('游戏中!')
run_count()
time.sleep(1)#延迟1秒
def run_count():
print('当前线程数量:',threading.active_count())
def single_thread():#单线程
coding()
game()
def muti_thread():#多线程
fun1=threading.Thread(target=coding)
fun2=threading.Thread(target=game)
fun1.start()
fun2.start()
if __name__=='__main__':
print('单线程')
single_thread()#
print('多线程')
muti_thread()
继承thread类
重构上面的代码
import threading,time
class codeWork(threading.Thread):#继承thread.Thread类
def __init__(self,name):
threading.Thread.__init__(self)
self.name=name#名字自定义
def run(self):
the_thread=threading.current_thread()
for i in range(2):
print('正在写python!',the_thread.name)
time.sleep(1)
class gameWork(threading.Thread):
def __init__(self,name):
threading.Thread.__init__(self)
self.name=name#名字自定义
def run(self):
the_thread=threading.current_thread()
for i in range(2):
print('游戏中',the_thread.name)
time.sleep(1)
def muti_thread():
th1=codeWork('写代码的进程')
th2=gameWork('游戏的进程')
th1.start()
th2.start()
if __name__=='__main__':
muti_thread()
全局变量的问题
不加线程锁
因为多线程执行的不确定性,粗暴的更改全局变量可能会造成bug
例:多线程执行value++,查看全局变量value的值
import threading
value=0
class global_Work1(threading.Thread):#继承thread.Thread类
def __init__(self,name):
threading.Thread.__init__(self)
self.name=name#名字自定义
def run(self):
the_thread=threading.current_thread()
global value # 定义全局变量
for i in range(1,20):
value+=1
print('全局变量c:',value,'\t运行的进程:',threading.active_count(),the_thread.name)
class global_Work2(threading.Thread):#继承thread.Thread类
def __init__(self,name):
threading.Thread.__init__(self)
self.name=name#名字自定义
def run(self):
the_thread=threading.current_thread()
global value # 定义全局变量
for i in range(1,20):
value+=1
print('全局变量c:',value,'\t运行的进程:',threading.active_count(),the_thread.name)
def muti_thread():
th1=global_Work1('全局变量测试1')
th2 = global_Work1('全局变量测试2')
th1.start()
th2.start()
if __name__=='__main__':
# global c # 定义全局变量
muti_thread()
添加线程锁Lock(线程同步)
threading.Lock()
- acquire()
- release()
queue线程安全队列
内置的线程安全模块queue(同步、安全,fifo)
- qsize() 队列大小
- empty() 队列是否为空
- full() 队列是否满了
- get()队列的最后一个数据
- put() 数据加入队列
例:queue同步执行
import queue
import threading
import time
exitFlag = 0
class myThread(threading.Thread):
def __init__(self, threadID, name, q):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.q = q
def run(self):
print("开始 " + self.name)
process_data(self.name, self.q)
print("退出 " + self.name)
def process_data(threadName, q):
while not exitFlag:
queueLock.acquire()
if not workQueue.empty():
data = q.get()
queueLock.release()#获取线程之后释放锁
print("%s 运行 %s" % (threadName, data))
else:
queueLock.release()
time.sleep(1)
if __name__=='__main__':
threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["线程1", "线程2", "线程3", "线程4", "线程5"] #
queueLock = threading.Lock() # 线程锁
workQueue = queue.Queue(10) # 大小为10的队列
threads = []
threadID = 1
# 创建新线程
for tName in threadList: # 分配线程名字
thread = myThread(threadID, tName, workQueue)
thread.start()
threads.append(thread)
threadID += 1
# 填充队列
queueLock.acquire() # 加锁
for word in nameList:
workQueue.put(word)
queueLock.release() # 解锁
# 等待队列清空
while not workQueue.empty():
pass#占位
# 通知线程是时候退出
exitFlag = 1
# 等待所有线程完成
for t in threads:
t.join()
print("Exiting Main Thread")