1.线程
#进程是资源分配的最小单位 (包工头)
#线程是程序调度的最小单位 (工人)
#线程的缘起
资源分配需要分配内存空间,分配cpu:
分配的内存空间存放着临时要处理的数据等,比如要执行的代码,数据
而这些内存空间是有限的,不能无限分配
目前配置高的主机,5万个并发已是上限.线程概念应用而生.
#线程的特点
线程是比较轻量级,能干更多的活,一个进程中的所有线程资源是共享的.
一个进程至少有一个线程在工作
1.1进程中可以包含多个线程
import os,random,time from threading import Thread from multiprocessing import Process def func(num): time.sleep(random.uniform(0.1,1)) print("子线程",num ,os.getpid()) for i in range(10): t = Thread(target=func,args=(i,)) t.start()
从上代码可以看出,主线程加子线程一共有11个线程!
1.2 并发多线程 和 多进程,谁的速度快 => 多线程
import os,random,time from threading import Thread from multiprocessing import Process def func(num): print("子线程",num ,os.getpid()) if __name__ == '__main__': startime = time.perf_counter() lst = [] for i in range(1000): t = Thread(target=func,args=(i,)) t.start() lst.append(t) for i in lst: # print(i) i.join() endtime = time.perf_counter() print("多线程执行的时间:",endtime-startime) # 0.31189374899986433 # 多进程的执行时间 startime = time.perf_counter() lst = [] for i in range(1000): p = Process(target=func,args=(i,)) p.start() lst.append(p) for i in lst: i.join() endtime = time.perf_counter() print("多进程执行的时间:",endtime-startime) # 多进程执行的时间: 2.034676988994761
1.3多线程共享同一份进程资源
import os,random,time from threading import Thread from multiprocessing import Process num = 100 lst = [] def func(): # 异步并发程序 time.sleep(1) global num num -= 1 for i in range(100): t = Thread(target=func) t.start() lst.append(t) for i in lst: i.join() print(num)
注意:线程与线程之前是异步并发的
1.4 线程相关的函数
线程.is_alive() 检测线程是否仍然存在
线程.setName() 设置线程名字
线程.getName() 获取线程名字
1.currentThread().ident 查看线程id号
2.enumerate() 返回目前正在运行的线程列表
3.activeCount() 返回目前正在运行的线程数量
import os,random,time from threading import Thread from multiprocessing import Process def func(): # pass time.sleep(0.5) t = Thread(target=func) print(t) # <Thread(Thread-1, initial)> t.start() print(t.is_alive()) # True print(t.getName()) # Thread-1 t.setName("producer_wang1号") print(t.getName()) # producer_wang1号 # (2).enumerate() 放回目前正在运行的线程列表 from threading import enumerate from threading import currentThread def func(): print("子进程:",currentThread().ident) # 查看线程id号 time.sleep(0.5) for i in range(10): t = Thread(target=func) t.start() print(enumerate()) print(len(enumerate())) # 11 # (3).activeCount() 返回目前正在运行的线程数量 (了解) from threading import activeCount from threading import currentThread def func(): print("子进程:",currentThread().ident) time.sleep(0.5) for i in range(10): t = Thread(target=func) t.start() print(activeCount()) # 11
2.守护线程
等待所有线程全部执行结束之后,再终止。守护所有线程。主程序默认等待所有的子线程
from threading import Thread import time def func1(): while True: time.sleep(0.5) print("我是子线程func1函数") def func2(): print("func2 start...") time.sleep(3) print("func2 end ...") t1 = Thread(target=func1) # 设置守护线程,在start调用之前进行设置 setDaemon t1.setDaemon(True) t1.start() t2 = Thread(target=func2) t2.start() print("我是主线程。。。")
3.线程锁lock
from threading import Thread,Lock n = 0 def func1(lock): global n for i in range(10000): lock.acquire() # 写法一 n -=1 lock.release() def func2(lock): global n for i in range(10000): # 写法二 with lock: n += 1 if __name__ == '__main__': # 创建一把锁 lock = Lock() lst = [] for i in range(10): # 10个线程专门负责加1 t1 = Thread(target=func1,args=(lock,)) # 10个线程专门负责减1 t2 = Thread(target=func2,args=(lock,)) t1.start() t2.start() lst.append(t1) lst.append(t2) for i in lst: i.join() print("主进程执行结束。。。") print(n)
4.信号量 Semaphore
from threading import Semaphore,Thread import time def func(i,sem): with sem: print(i) time.sleep(10) sem = Semaphore(6) # 批量上锁6把 for i in range(20): Thread(target=func,args=(i,sem)).start()