-
进程: 生产者消费者模型
-
编程思想,模型,设计模式,理论等等,都是交给你一种编程的方法,以后你遇到类似的情况套用即可
-
生产者消费者三要素:生产者:产生数据的
消费者:接收数据做进一步处理的
容器:盆(队列)
队列容器作用:缓冲的作用,平衡生产力与消费力,解耦
from multiprocessing import Process from multiprocessing import Queue import time import random def producer(q,name): for i in range(1,6): time.sleep(random.randint(1,2)) res = f'{i}号包子' q.put(res) print(f'生产者{name}生产了{res}') def consumer(q,name): while 1: try: food = q.get(timeout=3) time.sleep(random.randint(1,3)) print(f'消费者{name}吃了{food}') except Exception: return if __name__ == '__main__': q = Queue() p1 = Process(target=producer,args=(q,'上约')) p2 = Process(target=consumer,args=(q,'海购')) p1.start() p2.start()
-
-
线程的理论知识
- 什么是线程(一条流水线的工作流程)
- 开启一个进程:在内存中开启一个进程空间,然后将主进程的所有的资源数据复制一份,然后调用线程去执行代码
- 进程是资源单位,线程是执行单位
- 线程vs进程
- 开启进程的开销非常大,比开启线程的开销大很多.
- 开启线程的速度非常快.要快几十倍到上百倍.
- 线程线程之间可以共享数据,进程与进程之间需借助队列等方法实现通信.
- 线程的应用
- 并发: 一个cpu 看起来像是同时执行多个任务.
- 单个进程开启三个线程.并发的执行任务.
- 开启三个进程并发的执行任务.
- 开启多线程就非常好了:数据共享, 开销小,速度快.
- 什么是线程(一条流水线的工作流程)
-
开启线程的两种方式
第一种:函数的方式 # from threading import Thread # import time # def task(name): # print(f'{name} is running') # time.sleep(1) # print(f'{name} is gone') # # if __name__ == '__main__': # t1 = Thread(target=task,args=('长兴',)) # t1.start() # print('==主线程') 第二种:类的方式 from threading import Thread import time class MyThread(Thread): def __init__(self,name): super().__init__() self.name = name def run(self): print(f'{self.name} is running') time.sleep(1) print(f'{self.name} is gone') if __name__ == '__main__': t1 = MyThread('长兴') t1.start() print('===主线程')
-
线程vs进程的代码对比
- 开启速度对比
# 多进程 # from threading import Thread # from multiprocessing import Process # import os # def work(): # print('hello') # if __name__ == '__main__': # t = Process(target=work) # t.start() # print('主线程/主进程') 永远先执行主进程代码 # 多线程 from threading import Thread import time def task(name): print(f'{name} is running') time.sleep(1) print(f'{name} is gone') if __name__ == '__main__': t1 = Thread(target=task,args=('海购',)) t1.start() print('===主线程')
- 对比pid
# from multiprocessing import Process # import time # import os # def task(name): # print(f'子进程:{os.getpid()}') # print(f'主进程:{os.getppid()}') # if __name__ == '__main__': # p=Process(target=task,args=('长兴',)) # p2=Process(target=task,args=('长兴2',)) # p.start() # p2.start() # print(f'主进程{os.getpid()}') # 线程 from threading import Thread import os def task(): print(os.getpid()) if __name__ == '__main__': t1 = Thread(target=task) t2 = Thread(target=task) t1.start() t2.start() print(f'===主线程{os.getpid()}') 线程没有pid进程号,所求是该线程依赖的进程的pid号
- 同一个进程内线程共享内部数据
from threading import Thread import os x = 3 def task(): global x x = 100 if __name__ == '__main__': t = Thread(target=task) t.start() t.join() print(f'==主线程{x}') 同一进程内的资源数据对于这个进程的多个线程来说是共享的
-
线程的相关其他方法
Thread实例对象的方法 # isAlive(): 返回线程是否活动的。 # getName(): 返回线程名。 # setName(): 设置线程名。 threading模块提供的一些方法: # threading.currentThread(): 返回当前的线程变量。 子线程:<Thread(线程1, started 11252)> 主线程:<_MainThread(MainThread, started 5256)> # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。 [<_MainThread(MainThread, started 5256)>] 一个列表 # threading.activeCount(): 返回正在运行的线程数量,len(threading.enumerate())有相同的结果。
from threading import Thread from threading import currentThread from threading import enumerate from threading import activeCount import os import time x = 3 def task(): print(currentThread()) time.sleep(1) print('666') print(123) if __name__ == '__main__': t1 = Thread(target=task,name='线程1') t2 = Thread(target=task,name='线程2') t1.start() t2.start() time.sleep(2) print(t1.isAlive()) print(t1.getName()) t1.setName('子线程-1') print(t1.name) print(currentThread()) print(enumerate()) print(activeCount()) print(f'===主线程{os.getpid()}')
-
守护线程
# join:阻塞,告知主进程要等待我子进程结束之后,再执行主进程 from threading import Thread import time def task(name): print(f'{name} is running') time.sleep(1) print(f'{name} is gone') if __name__ == '__main__': start_time = time.time() t1 = Thread(target=task,args=('海购',)) t2 = Thread(target=task,args=('海购1',)) t3 = Thread(target=task,args=('海购2',)) t1.start() t1.join() t2.start() t2.join() t3.start() t3.join() print(f'===主线程{time.time()-start_time}') ===主线程3.0048482418060303 # 守护进程 from multiprocessing import Process import time def foo(): print(123) time.sleep(1) print('end123') def bar(): print(456) time.sleep(2) print('end456') if __name__ == '__main__': p1 = Process(target=foo,) p2 = Process(target=bar,) p1.daemon = True p1.start() p2.start() print('==主') ==主 456 end456 # 守护线程 from threading import Thread import time def sayhi(name): print('你滚!') time.sleep(2) print(f'{name} say hello') if __name__ == '__main__': t = Thread(target=sayhi,args=('长兴',)) t.daemon = True/t.setdaemon(True) t.start()#线程的开启速度要比进程快很多 print('主线程') 你滚! 主线程 -------------------------------------***------------------------------------ from threading import Thread import time def foo(): print(123) time.sleep(1) print('end123') def bar(): print(456) time.sleep(3) print('end456') t1 = Thread(target=foo) t2 = Thread(target=bar) t1.daemon = True t1.start() t2.start() print('main------') 123 456 main------ end123 end456 主线程什么时候结束? 守护线程 等待 非 守护 子线程以及 主线程结束 之后,结束 from threading import Thread import time def foo(): print(123) time.sleep(3) print('end123') def bar(): print(456) time.sleep(1) print('end456') t1 = Thread(target=foo) t2 = Thread(target=bar) t1.daemon = True t1.start() t2.start() print('main------') 123 456 main------ end456
-
互斥锁
# from threading import Thread # import time # import random # x = 100 # # def task(): # time.sleep(random.randint(1,2)) # global x # temp = x # time.sleep(random.randint(1, 3)) # temp = temp - 1 # x = temp # # # if __name__ == '__main__': # l1 = [] # for i in range(100): # t = Thread(target=task) # l1.append(t) # t.start() # # for i in l1: # i.join() # print(f'主线程{x}') # 多个任务公抢一个数据,保证数据的安全的目的,要让其串行 from threading import Thread from threading import Lock import time import random x = 100 def task(lock): lock.acquire() # time.sleep(random.randint(1,2)) global x temp = x time.sleep(0.01) temp = temp - 1 x = temp lock.release() if __name__ == '__main__': mutex = Lock() for i in range(100): t = Thread(target=task,args=(mutex,)) t.start() time.sleep(3) print(f'主线程{x}')