线程
线程:
操作系统调度的最小单位, 一串指令集和,要操作cpu,至少要先创建一个线程,叫驻现场
同一个进程里的线程共享同一块内存
同一个进程里的两个线程内存共享
创建新线程很简单
一个线程可以操作同一个进程里线程
主线程是程序本身,不是自己建立的线程
调用操作系统,c语言的pthread
threading.current_thread(),查看当前线程角色
threading.active_count(),查看当前线程数量
thread_name.join() #线程获取到执行结果之前不继续run
import threading import time # 普通写法 def run(n): print("task", n) time.sleep(2) t1 = threading.Thread(target=run, args=("t1",)) t2 = threading.Thread(target=run, args=("t2",)) t1.start() t2.start() # 继承写法 class MyThread(threading.Thread): def __init__(self, n): super(MyThread, self).__init__() self.n = n def run(self): print("runing task ", self.n) time.sleep(2) t3 = MyThread("t3") t4 = MyThread("t4") t3.start() t4.start()
GIL锁:
全局解释器锁(CPython独有)
保证同一时间只能有一个线程执行
多线程没有线程锁执行步骤:
0,源生数据n=0
1,线程池生成py thread a
2,申请gil锁,以便操作cpu
3,调用系统源生线程
4,在cpu上执行
5,执行时间到了,被要求释放gil锁,解释器每一百条切换一次锁
6,第二个线程拿到公共数据 py thread b
7,申请gil
8,调用源生线程
9,在cpu上执行
10,完成公共数据加减操作n=0+1
11,反馈给公共数据
12,线程a再次申请gil锁
13,计算完毕n=0+1
14,反馈给公共数据n=1
线程锁(mutex):
保证同一时间只有一个线程修改数据
lock = threading.Lock()
lock.acquire()
lock.release()
递归锁(Rlock):
在一个大锁中还要在包含子锁,避免死循环
threading.RLock()
信号量(Semaphore)
允许一定量的线程更改数据,跟锁的区别是有多把锁
semaphore = threading.BoundedSemaphore(5) #同时允许多少个线程在活动
semaphore.acquire()
semaphore.release()
event
是简单的同步对象
event = threading.Event()
event.set() #标识位被设置,绿灯,直接同行
event.clear() #标识位被清空,红灯,等待再次set
event.wait() #等待标识位被设置
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # -*- Author:Hinimix -*- import time import threading event = threading.Event() def lighter(): count = 0 event.set() while True: if count > 5 and count < 10: event.clear() print("\033[41;1mred light \033[0m", count) elif count > 10: count = 0 event.set() else: print("\033[46;1mgreen light \033[0m", count) time.sleep(1) count += 1 def car(name): while True: time.sleep(1) if event.is_set(): print(name, "is running") else: print(name, "is waiting") event.wait() light = threading.Thread(target=lighter,) light.start() car1 = threading.Thread(target=car,args=("hondacity",)) car1.start() car2 = threading.Thread(target=car,args=("benz",)) car2.start() car3 = threading.Thread(target=car,args=("toyoto",)) car3.start()
queue(线程queue)
class queue.Queue(maxsize=0) #先入先出
class queue.LifoQueue(maxsize=0) #后入先出 last in first out
class queue.PriorityQueue(maxsize=0) #按优先级
queue.qsize() #查询队列后面还有多长
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # -*- Author:Hinimix -*- import queue q = queue.Queue(maxsize=100) #指定队列长度 q.put("h1") q.put("h2") print(q.qsize()) print(q.get()) print(q.get()) # print(q.get()) #队列没有数据时候会卡住 # print(q.get(block=False)) #队列没有数据时候会不会卡住 print(q.get_nowait()) #队列没有数据时候会不会卡住
有优先级的队列
import queue q = queue.PriorityQueue(maxsize=10) q.put((10, "h1")) q.put((-20, "h2")) # 优先级越低越先出 print(q.get()) print(q.get())
多线程使用场景:
不适合CPU密集操作型任务, 适合IO密集型任务