多线程
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")