线程
1,生产者消费者模型
- 什么是生产者与消费者模型
- 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题,生产者和消费者之间不直接通讯,而通过阻塞队列来通讯,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力
- 在并发编程中使用生产者和消费者模式能够解决大多数并发问题,该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度
- 基于队列(容器)实现生产者和消费者模型
2,线程
- 定义
- 进程是一个资源单位,线程是CPU上的执行单位
- 一个进程里面开多个线程,共享一个进程里面的内存空间数据
3,开启线程的两种方式
-
进程的开启必须是在main下开启,但是线程的开启不是一定在main下开启
-
第一种:在main下开启,和进程的开启方式一样
-
1 1.创建线程的开销比创建进程的开销小,因而创建线程的速度快 2 from multiprocessing import Process 3 from threading import Thread 4 import os 5 import time 6 def work(): 7 print('<%s> is running'%os.getpid()) 8 time.sleep(2) 9 print('<%s> is done'%os.getpid()) 11 if __name__ == '__main__': 12 t=Thread(target=work,) 14 t.start() 15 print('主',os.getpid())
-
-
第二种:继承与Thread类方式的开启
-
1 from threading import Thread 2 import time 3 class Work(Thread): 4 def __init__(self,name): 5 super().__init__() 6 self.name = name 7 def run(self): 8 # time.sleep(2) 9 print('%s say hell'%self.name) 10 if __name__ == '__main__': 11 t = Work('egon') 12 t.start() 13 print('主')
-
线程vs进程的对比
- 开启一个进程,会在内存中开辟一个口进程空间,将主进程的数据全部复制一份,通过线程执行代码
- 创建线程的开销比进程小,创建进程需要开空间,而线程存在于进程里面,线程不需要开空间
- 同一个进程内的多线程之间可以共享数据,进程与进程之间是相互空间隔离的,需借助队列的方法实现通行
- 同一个进程下开多个子进程的pid是不同的,但是开多个线程的pid是相同的
线程的相关其他方法
-
Thread实例对象方法
- isAlive() :返回线程是否是活动的
- getName():返回线程名
- setName():设置线程名
-
threading模块提供的一些方法
- threading.currentThread():返回当前的线程变量
- Threadind.enumerate(): 返回一个正在运行的线程的list
- threading.activeCount():返回正在运行的线程数量,与len(Threadind.enumerate())有相同的效果
-
其他属性
-
1 from threading import Thread 2 from multiprocessing import Process 3 import time,os,threading 4 def work(): 5 time.sleep(2) 6 print('%s is running' % threading.currentThread().getName()) 7 print(threading.current_thread()) #其他线程 8 print(threading.currentThread().getName()) #得到其他线程的名字 9 if __name__ == '__main__': 10 t = Thread(target=work) 11 t.start() 12 13 print(threading.current_thread().getName()) #主线程的名字 14 print(threading.current_thread()) #主线程 15 print(threading.enumerate()) #连同主线程在内有两个运行的线程 16 time.sleep(2) 17 print(t.is_alive()) #判断线程是否存活 18 print(threading.activeCount()) 19 print('主')
-
守护线程
-
join与守护线程
- 主进程等所有的非守护的子进程结束他才结束(回收他的字进程资源):有父子关系
- 主线程等非守护线程全部结束它才结束:没 父子关系
-
守护线程与守护进程的区别
- 守护进程:主进程会等到所有的非守护进程结束,守护进程随着主进程的结束也结束
- 守护线程:主线程等到非守护线程全部结束才结束,
-
实例
-
from multiprocessing import Process from threading import Thread,currentThread import time,os def talk1(): time.sleep(2) print('hello') def talk2(): time.sleep(2) print('you see see') if __name__ == '__main__': t1 = Thread(target=talk1) t2 = Thread(target=talk2) # t1 = Process(target=talk1) # t2 = Process(target=talk2) t1.daemon = True t1.start() t2.start() print('主线程',os.getpid()) ######################################## 主线程 11288 you see see hello ###############或者##################3 主线程 5664 hello you see see
-
#3 --------迷惑人的例子 from threading import Thread import time def foo(): print(123) # time.sleep(10) #如果这个等的时间大于下面等的时间,就把不打印end123了 time.sleep(2) #如果这个等的时间小于等于下面等的时间,就把end123也打印了 print('end123') def bar(): print(456) # time.sleep(5) time.sleep(10) print('end456') if __name__ == '__main__': t1 = Thread(target=foo) t2 = Thread(target=bar) t1.daemon = True #主线程运行完了守护的那个还没有干掉, # 主线程等非守护线程全都结束它才结束 t1.start() t2.start() print('main---------') #############大于################## 123 456 main--------- end456 ##############小于等于############# 123 456 main--------- end123 end456
-