一、进程间通信——队列(multiprocess.Queue)
队列:先进先出。堆栈:先进后出。
概念介绍:创建共享的进程队列,可以通过Queue实现多进程之间的数据传递。
from multiprocessing import Queue q = Queue(3) # 括号内可以传参数 表示的是这个队列的最大存储数 q.put(1) # 往队列中添加数据 q.put(2) # print(q.full()) # 判断队列是否满了 q.put(3) # q.put(4) # 当队列满了之后,再放入数据不会报错,会原地等待 直到队列中有数据被取走(此时为阻塞态) print(q.get()) print(q.get()) print(q.empty()) # 判断队列中的数据是否取完 print(q.get()) # print(q.get_nowait()) # 取值,如果没有值会直接报错 # print(q.get()) # 当队列中的数据被取完之后,再次去取值,程序就会阻塞,直到有人往队列中放入值。
其中(full,get_nowait,empty)都不适用于多进程的情况
二、线程
1.什么是线程?为何有线程?怎么用线程?
1)什么是线程
线程是一个抽象的概念。(三个线程就是有三段代码在运行,三个进程就是有三个内存空间建立)。
进程只是资源单位。线程才是执行单位。
将内存比如成工厂,那么进程就相当于是工厂里面的车间,而你的线程就相当于是车间里面的流水线。
ps:每个进程都自带一个线程,线程才是CPU真正的执行单位,进程只是在线程运行过程中提供代码运行所需要的资源。
qq进程:qq资源相关的数据占了一个独立的空间。(申请一个内存空间,中间产生的数据往里放)
2)为何有线程
一个进程内可以起多个线程,并且线程与线程之间数据是共享的。
ps:开启线程的开销要远远小于开启进程的开销。
2.开启线程的两种方式
开线程不需要写到main下,但是为了规范还是要写main。
方式一:导入Thread模块 from threading import Thread import time def task(name): print('%s is running' %name) time.sleep(3) if __name__ == '__main__': t=Thread(target=task,args=('egon',)) t.start() print('主线程') 方式二:创建类继承Thread from threading import Thread import time class MyThread(Thread): def run(self): print('%s is running' %self.name) time.sleep(3) if __name__ == '__main__': t=MyThread() t.start() print('主线程')
3 线程vs进程
同一进程内的线程们共享该进程内的资源,不同进程内的线程资源肯定是隔离的。
创建线程的开销比创建进程要小得多。
1)、 线程中没有父子关系。相较于子线程、主线程特殊之处在于其代变了主进程的生命周期。
主进程等待子进程结束然后结束,是为子进程回收资源。
主线程等待子线程结束然后结束,是等待这个进程的代码(其他非守护线程)执行完毕。
2)、同一个进程中的所有线程pid都是一样的,且资源共享。
3)、 线程创建开销小:子线程创建不需要向操作系统申请内存空间,直接执行程序。