1 什么是线程
进程:资源单位 #车间
线程:实际执行单位 #车间里面的实际工作的流水线 需要资源就问进程要
注意:每一个进程中都会自带一个线程(人为命名为:主线程)
2 为什么要有线程
开一个线程:
申请内存空间 耗时
将代码拷贝到申请的内存空间中 耗时
开线程:
不需要申请内存空间
#开启线程的速度非常快,几乎代码执行完线程就已经开启
开线程的开销远远小于开进程的开销!!
3 如何使用线程
1 线程理论:
进程:资源单位
线程:实际执行单位
2 创建线程的两种方式:
① 定义方法Thread(target=task, args=('egon',))
② 定义一个类 继承Theread 定义__init__为保证安全先super().__init__()
必须有run方法
3 join方法
主线程等子线程结束
4 线程对象的其他属性和方法
active_count() 当前存活的线程数
current_thread().name 当前线程的名字
os.getpid() 进程号(主线程,子线程指向的都是同一个进程号的pid)
5 守护线程:
线程启动前用daemon=True 声明
6 线程间数据是否隔离?
线程之间数据是共享
多个线程操作同一份数据 会出现数据不安全的情况
涉及到多个线程或进程操作同一份数据的时候,通常都需要将 并行 并发 变成串行
虽然牺牲了效率 但是提高了数据的安全性
针对不同的数据,需要加不同的锁
锁(独立卫生间)
7 线程互斥锁
开启线程的两种方式
开启线程的两种方式: 方式1: from threading import Thread import time def task(name): print('%s is running' % name) time.sleep(1) print('%s is over' % name) if __name__ == '__main__': t = Thread(target=task, args=('egon',)) t.start() #开启线程的速度非常快,几乎代码执行完线程就已经开启 print('主') #主线程结束后 不会立即结束进程,会等待所有的 非守护线程都结束完(非守护线程还要用进程的资源)才结束。 #就像主线程用完作业完后需要关闭车间的电,但是车间里别的流水线还要用电 所以不能立即停电 egon is running主 egon is over 方式二: from threading import Thread import time class MYThread(Thread): def __init__(self, name): super().__init__() self.name = name def run(self): print('%s is running ' % self.name) time.sleep(1) print('%s is over ' % self.name) if __name__ == '__main__': t = MYThread('jack') t.start() print('主') jack is running 主 jack is over
线程对象的其他属性和方法
线程对象的其他属性和方法: from threading import Thread,active_count,current_thread import os import time def task(name): print('%s is running'%name,os.getpid(),current_thread().name) time.sleep(1) print('%s is over'%name) # def info(name): # print('%s is running'%name,current_thread().name) # time.sleep(1) # print('%s is over'%name) t=Thread(target=task,args=('name',)) t.start() t.join() print(active_count()) #当前存活的线程数 print(os.getpid()) print(current_thread().name) name is running 5128 Thread-1 #子线程 5128 子线程名字 name is over #name is over 1 #当前存活的线程数 1 5128 #5128 MainThread #主线程名字
守护线程
from threading import Thread import time def task(name): print('%s is running' % name) time.sleep(1) print('%s is over' % name) if __name__ == '__main__': t = Thread(target=task, args=('小王',)) t.daemon = True t.start() print('主') 小王 is running主
线程间数据是共享的
#线程之间数据共享 from threading import Thread x=100 def task(): global x x=666 t=Thread(target=task) t.start() t.join() #等待子线程 结束后再查看 print(x) #666
线程互斥锁
线程互斥锁: from threading import Thread,Lock #线程 锁 import time mutex=Lock() n=100 def task(): global n mutex.acquire() #抢锁 tem=n time.sleep(0.1) n=tem-1 print(n) #99 98 97 96....0 mutex.release() #释放锁 t_list=[] for i in range(100): t=Thread(target=task) t.start() #启动子线程 t_list.append(t) #把子线程对象添加到列表里 for t in t_list: t.join() #等所有的子线程结束完 才进行下面代码 print('主',n) #最后主线程是0