pytthon3多线程
python调用的是操作系统的原生线程,
表面是多线程,同一时间只有一个线程在运行,我们看到的多线程并发的现象,只是python利用的cpu的上下文切换,
cpu的计算速度很快,所以看起来是并发的效果。
所有如果你的代码是cpu密集型,用单线程比多线程效率可能更高,
如果是io密集型,用多线程的效率就很高了。
不够如果要用python确实的进行多线程,python里面也有折中的方法,需要几个线程就开启几个进程,每个进程里面的线程就可以起到多线程的真实效果。
最简单的python3多线程,代码如下:
import threading import time def run(t): print(t) time.sleep(1) t1 = threading.Thread(target=run, args=("t1", )) t2 = threading.Thread(target=run, args=("t2", )) t1.start() t2.start()
用类的方式开启多线程:
import threading import time """ 以类的方式启用多线程 """ class MyThread(threading.Thread): def __init__(self, n, sleep_time): super(MyThread, self).__init__() self.n = n self.sleep_time = sleep_time def run(self): print("task:", self.n) time.sleep(self.sleep_time) print("task %s done" % self.n) t1 = MyThread("t1", 2) t2 = MyThread("t2", 4) t1.start() t2.start() #等待t1线程执行完毕 t1.join() print("----main thread----")
开启50个线程,并计算运行时间:
import threading import time start_time = time.time() #创建空列表,存储每个线程对象 t_objs = [] def run(n): #打印当前运行的线程 print("task, ", n, threading.current_thread()) time.sleep(1) print("task %s done" % n) #开启50个线程 for i in range(50): t = threading.Thread(target=run, args=(i, )) t.start() t_objs.append(t) #等待所有线程执行完毕 for i in t_objs: t.join() print("----all thread done----,", threading.current_thread()) print("cost:", time.time() - start_time)
守护线程:
import threading import time """ 守护线程 主人死了,仆人殉葬 """ start_time = time.time() t_objs = [] def run(n): #打印当前所在线程 print("task, ", n, threading.current_thread()) time.sleep(1) print("task %s done" % n) for i in range(50): t = threading.Thread(target=run, args=(i, )) #守护线程,主线程执行完就退出程序,不等子线程 t.setDaemon(True) t.start() t_objs.append(t) #等待所有线程执行完毕再继续主线程 #for i in t_objs: #t.join() print("----all thread done----,", threading.current_thread()) print("cost:", time.time() - start_time)
GIL全局锁:
import threading, time """ GIL 全局解释器锁 同一时间只有一个线程修改数据 同时修改数据的时候,避免出现差错 """ def count(): #加锁,每个线程进来都加锁,执行完当前线程之后,下一个线程再进来 lock.acquire() global num num += 1 print("curren_thread:", threading.current_thread()) time.sleep(1) #解锁 lock.release() num = 0 #申请一把解释器锁 lock = threading.Lock() t_objs = [] for i in range(50): t = threading.Thread(target=count) t.start() t_objs.append(t) #子线程全部执行完毕,再继续主线程 for i in t_objs: i.join() print("num:", num)
递归全局锁:
import threading, time """ 递归锁 锁多的时候要用递归锁 避免钥匙搞乱,造成死循环 """ def run1(): global num1 print("grab the first part data") lock.acquire() num1 += 1 lock.release() return num1 def run2(): global num2 print("grab the second part data") lock.acquire() num2 += 1 lock.release() return num2 def run3(): lock.acquire() res1 = run1() print("----between run1 and run2----") res2 = run2() lock.release() print(res1, res2) lock = threading.RLock() num1, num2 = 0, 0 t_objs = [] for i in range(10): t = threading.Thread(target=run3) t.start() t_objs.append(t) for i in t_objs: i.join() while threading.active_count() != 1: print(threading.active_count()) else: print("all threads done") print(num1, num2)
BoundedSemaphore信号量:
import threading, time def run(m): semaphore.acquire() print("task ", m) time.sleep(1) m += 1 semaphore.release() #设置信号量为5,最多允许5个线程同时运行 semaphore = threading.BoundedSemaphore(2) for i in range(10): t = threading.Thread(target=run, args=(i, )) t.start() while threading.active_count() != 1: pass else: print("all threads done")
queue队列:
import queue, threading, time """ 队列: queue.Queue() 先进先出 queue.FiloQueue() 先进后出 queue.PrioriteQueue() 设置队列优先级 qsize() 打印队列大小 """ q = queue.Queue(maxsize=10) #生产者 def producer(name): count = 0 while True: print("[%s]生产了骨头[%s]" % (name, count)) q.put(count) count += 1 time.sleep(2) #消费者 def consumer(name): while True: print("[%s]吃了骨头[%s]..." % (name, q.get())) time.sleep(3) p1 = threading.Thread(target=producer, args=("小白", )) c1 = threading.Thread(target=consumer, args=("鹿晗", )) c2 = threading.Thread(target=consumer, args=("皮几万", )) p1.start() c1.start() c2.start()
event事件:
import threading, time """ event事件 功能类似于标志位 设置了事件线程可以通过, 清楚设置为线程不能通过 """ def lighter(): counter = 0 event.set() while True: if counter > 5 and counter < 12: #清除标志位,阻塞,红灯 event.clear() print("\033[41;1mred light is on...\033[0m") elif counter > 12: #设置标志位,放行,绿灯 event.set() counter = 0 else: print("\033[42;1mgreen light is on...\033[0m") time.sleep(1) counter += 1 def car(name): while True: #绿灯 if event.is_set(): print("[%s] run!" % name) time.sleep(1) else: print("[%s] sees red light, waiting...." % name) event.wait() print("[%s] sees green light, start going...." % name) event = threading.Event() lighter = threading.Thread(target=lighter) lighter.start() landrover = threading.Thread(target=car, args=("landrover", )) tesla = threading.Thread(target=car, args=("tesla", )) landrover.start() tesla.start()