线程是一种多任务编程的方式,可使用计算机多核资源。线程又被称为轻量级的进程java
线程特征python
* 线程是计算机核心分配的最小单位
* 一个进程能够包含多个线程
* 线程也是一个运行过程,也要消耗计算机资源。多个线程共享其进程的资源和空间
* 线程也拥有本身特有的资源属性,好比指令集,TID等
* 线程不管建立仍是删除仍是运行资源消耗都小于进程
* 多个线程之间并行执行,互不干扰编程
from threading import Threadc#
t = Thread(target, [, args], [kwargs])安全
建立线程对象多线程
t.start() 启动线程并发
t.join([timeout]) 回收线程app
import threading import os a = 1 # 线程函数 def music(): print("进程pid号", os.getpid()) global a print("a = ",a) a = 10000 t = threading.Thread(target=music) # 建立线程对象 t.start() # 启动线程 print("进程pid号", os.getpid()) t.join() # 回收线程 print("Main a:",a) # 进程pid号 12549 # 进程pid号 12549 # a = 1 # Main a: 10000
os.getpid获取的是进程的pid号,线程是进程中的一个成员.ide
线程中改的变量,是进程中的变量.并无新开辟一个空间.函数
t.is_alive() 查看线程状态
t.name 线程名称 默认Thread-1
t.setName() 设置线程名称
threading.currentThread() 获取当前线程对象
1 from threading import Thread,currentThread 2 from time import sleep 3 4 #线程函数 5 def fun(sec): 6 print("线程属性测试") 7 sleep(sec) 8 #获取线程对象 getName()获取名字 9 print("%s 线程结束"%currentThread().getName()) 10 11 thread = [] 12 13 for i in range(3): 14 t = Thread(target = fun,name = "tedu%d"%i,\ 15 args = (3,)) 16 thread.append(t) 17 t.start() 18 print(t.is_alive()) #查看进程状态 19 20 thread[1].setName('Tarena') #设置线程名称 21 print(thread[2].name) #获取线程名称 22 23 #回收线程 24 for i in thread: 25 i.join() 26 27 # 线程属性测试 28 # True 29 # 线程属性测试 30 # True 31 # 线程属性测试 32 # True 33 # tedu2 34 # Tarena 线程结束 35 # tedu0 线程结束 36 # tedu2 线程结束
t.daemon
默认状况下,主线程的结束不会影响分支线程,若是设置为True则主线程退出分支线程也会退出
设置方法:
t.daemon = True
t.setDaemon()
线程daemon属性的设置在start前;通常设置daemon后不会使用join
from threading import Thread from time import sleep def fun(): sleep(3) print("线程属性测试") t = Thread(target=fun, name = "Tarena") # 主线程退出分支线程也退出 t.setDaemon(True) t.start() t.setName("Tedu") print("Name:",t.getName()) # 线程名称 print("Alive:",t.is_alive()) # 线程生命周期 print("is Daemon",t.isDaemon()) # 主进程随着分支进程退出
使用方法
from threading import Thread class ThreadClass(Thread): # 重写父类init def __init__(self, *args, **kwargs): self.attr = args[0] super().__init__() # 加载父类init def fun1(self): print("函数1") def fun2(self): print("函数2") # 重写run,逻辑调用 def run(self): self.fun1() self.fun2() t = ThreadClass("abc") t.start() t.join() # 函数1 # 函数2
1.通讯方法:线程间使用全局变量进行通讯
2. 共享资源争夺
3. 同步互斥机制
同步 : 同步是一种协做关系,为完成操做,多进程或者线程间造成一种协调,按照必要的步骤有序执行操做。
互斥 : 互斥是一种制约关系,当一个进程或者线程占有资源时会进行加锁处理,此时其余进程线程就没法操做该资源,直到解锁后才能操做。
from threading import Event
e = Event() 建立线程event对象
e.wait([timeout]) 阻塞等待e被set
e.set() 设置e,使wait结束阻塞
e.clear() 使e回到未被设置状态
e.is_set() 查看当前e是否被设置
from threading import Thread,Event s = None # 用于通讯 e = Event() # 建立event对象 def 杨子荣(): print("杨子荣前来拜山头") global s s = "天王盖地虎" e.set() # 对e设置 t = Thread(target=杨子荣) t.start() print("说对口令就是本身人") e.wait() # 阻塞等待口令说出 if s == '天王盖地虎': print("宝塔镇河妖") print("确认过眼神,你是对的人") else: print("打死他...") t.join()
from threading import Lock
lock = Lock() 建立锁对象
lock.acquire() 上锁 若是lock已经上锁再调用会阻塞
lock.release() 解锁
with lock: # 上锁
...
...
with代码块结束自动解锁
from threading import Thread,Lock a = b = 0 lock = Lock() # 定义锁 def value(): while True: lock.acquire() # 上锁 if a != b: print("a = %d,b = %d"%(a,b)) lock.release() # 解锁 t = Thread(target = value) t.start() while True: # 上锁 with lock: a += 1 b += 1 # 自动解锁 t.join()
GIL (全局解释器锁)
python ---》 支持线程操做 ---》IO的同步和互斥 --》 加锁 ----》 超级锁,给解释器加锁
后果:一个解释器,同一时刻只解释一个线程,此时其余线程须要等待。大大下降了python线程的执行效率
python GIL问题解决方案
* 修改c解释器
* 尽可能使用多进程进行并行操做
* python线程能够用在高延迟多阻塞的IO情形
* 不使用cpython c# java作解释器
分别测试 多进程 多线程 单进程执行相同的IO操做和CPU
#计算密集 def count(x,y): c = 0 while c < 7000000: x += 1 y += 1 c += 1 #io密集 def write(): f = open("test.txt",'w') for x in range(2000000): f.write("hello world\n") f.close() def read(): f = open("test.txt") lines = f.readlines() f.close()
操做的时间
#单进程程序 from test import * import time # t = time.time() # for i in range(10): # count(1,1) # print("Line cpu:",time.time() - t) t = time.time() for i in range(10): write() read() print("Line IO:",time.time() - t)
Line cpu: 8.15166711807251
Line IO: 6.841825246810913
from test import * import threading import time counts = [] t = time.time() for x in range(10): th = threading.Thread(target = count,args = (1,1)) th.start() counts.append(th) for i in counts: i.join() print("Thread cpu",time.time() - t)
from test import * import threading import time counts = [] def io(): write() read() t = time.time() for x in range(10): th = threading.Thread(target = io) th.start() counts.append(th) for i in counts: i.join() print("Thread IO",time.time() - t)
Thread cpu 8.414522647857666
Thread IO 6.023292541503906
from test import * import multiprocessing import time counts = [] t = time.time() for x in range(10): th = multiprocessing.Process\ (target = count,args = (1,1)) th.start() counts.append(th) for i in counts: i.join() print("Process cpu",time.time() - t)
from test import * import multiprocessing import time counts = [] def io(): write() read() t = time.time() for x in range(10): th = multiprocessing.Process(target = io) th.start() counts.append(th) for i in counts: i.join() print("Process IO",time.time() - t)
Process cpu 4.079084157943726
Process IO 3.2132551670074463
使用状况: