生产者消费者模型 开启线程的两种方式 多线程与多进程开启速度区别 线程进程pid 统一进程内线程是共享数据的 线程的其他方法 join与守护线程 互斥锁...

喜欢ヅ旅行 2023-10-10 10:19 78阅读 0赞

生产者消费者模型

进程:

​ 生产者消费者模型

​ 编程思想, 模型, 设计模式, 理论等等, 都是交给你一种编程的方法, 以后遇到类似的情况, 套用即可

生产者消费者模型三要素

​ 生产者: 产生数据的

​ 消费者: 接收数据做进一步处理的

​ 容器: 盆(队列)

队列容器的作用

​ 起到缓冲的作用, 平衡生产力与消费力, 解耦

实例

  1. import time import random from multiprocessing import Process, Queue 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"\033[31;0m 消费者{name} 吃了{food} \033[0m") except Exception: return if __name__ == '__main__': q = Queue() p1 = Process(target=producer, args=(q, "孙宇")) p2 = Process(target=consumer, args=(q, "海狗")) p1.start() p2.start() """ 生产者孙宇 生产了1号包子 生产者孙宇 生产了2号包子 消费者海狗 吃了1号包子 生产者孙宇 生产了3号包子 消费者海狗 吃了2号包子 生产者孙宇 生产了4号包子 生产者孙宇 生产了5号包子 消费者海狗 吃了3号包子 消费者海狗 吃了4号包子 消费者海狗 吃了5号包子 """

开启线程的两种方式

进程是资源单位, 线程是执行单位

什么是线程

​ 一条流水线的工作流程.

进程:

​ 在内存中开启一个进程空间, 然后将主进程的所有的资源数据复制一份, 然后调用CPU去执行这些代码

具体描述进程:

​ 在内存中开启一个进程空间, 然后将主进程的所有的资源数据复制一份, 然后调用线程去执行代码

执行流程

​ 主线程子线程没有地位之分, 但是一个主线程在执行, 执行完, 要等待其他非守护子线程执行完之后, 才能结束主线程, 结束本进程

  1. # 第一种方式 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("===主线程") # 线程没有主次之分 """ 李业 is running ===主线程 李业 is gone """ # 第二种方式 from threading import Thread import time class MyThread(Thread): def __init__(self, name, l1, s1): super(MyThread, self).__init__() self.name = name self.l1 = l1 self.s1 = s1 def run(self): print(f"{self.name} is running") time.sleep(1) print(f"{self.name} is gone") if __name__ == '__main__': t1 = MyThread("李业", [1,2,3], "180") t1.start() print("===主线程") """ 李业 is running ===主线程 李业 is gone """

多线程与多进程开启速度区别

  1. from multiprocessing import Process import time def work(): print("hello") if __name__ == '__main__': start_time = time.time() lst = [] for i in range(10): t = Process(target=work) t.start() lst.append(t) for i in lst: i.join() print(time.time() - start_time) """ hello hello hello hello hello hello hello hello hello hello 1.004307746887207 """ # 多线程 from threading import Thread import time def task(): print("hello") if __name__ == '__main__': start_time = time.time() lst = [] for i in range(10): t = Thread(target=task) t.start() lst.append(t) for i in lst: i.join() print(time.time() - start_time) """ hello hello hello hello hello hello hello hello hello hello 0.0019998550415039062 """

​ 开启进程的开销非常大, 比开启线程的开销大很多.

​ 开启线程的速度非常快, 要快几十倍到上百倍.

线程进程pid

  1. # 进程pid from multiprocessing import Process import os def task(): print(f"子进程:{os.getpid()}") print(f"主进程:{os.getppid()}") if __name__ == '__main__': p1 = Process(target=task) p2 = Process(target=task) p1.start() p2.start() print(f"==主:{os.getpid()}") """ ==主:51060 子进程:51128 主进程:51060 子进程:42856 主进程:51060 """ # 线程pid from threading import Thread import os def task(): print(os.getpid()) if __name__ == '__main__': t = Thread(target=task) t1 = Thread(target=task) t.start() t1.start() print(f"===主线程:{os.getpid()}") """ 51768 51768 ===主线程:51768 """ # 多线程在同一个进程内, 所以pid都一样

同一进程内线程是共享数据的

​ 线程与线程之间可以共享数据, 进程与进程之间需要借助队列等方法实现通信

​ 同一进程内的资源数据对于这个进程内的多个线程来说是共享的

1730033-20190823080440213-1259503193.png

线程的应用

​ 并发: 一个CPU看起来像是同时执行多个任务

​ 单个进程开启三个线程, 并发的执行任务

​ 开启三个进程并发的执行任务

​ 文本编辑器:

​ 1.输入文字

​ 2.在屏幕上显示

​ 3.保存在磁盘中

​ 开启多线程就非常简单了:

​ 数据共享, 开销小, 速度快

  1. from threading import Thread x = 3 def task(): global x x = 100 if __name__ == '__main__': t1 = Thread(target=task) t1.start() t1.join() print(f"===主线程{x}") """ ===主线程100 """

线程的其他方法

  1. from threading import Thread, current_thread, enumerate, activeCount import os import time x = 3 def task(): time.sleep(1) print(666) if __name__ == '__main__': t1 = Thread(target=task) t2 = Thread(target=task) t1.start() t2.start() print(t1.isAlive()) # 判断子线程是否存活 print(t1.getName()) # 获取子线程名字 t1.setName("子进程-1") # 修改子线程名字 print(t1.name) # 获取子线程的名字 *** print(current_thread()) # 获取当前线程的内容 print(enumerate()) # 获取当前进程下的所有线程,以列表形式展示 print(activeCount()) # 获取当前进程下的所有存活线程的数量 print(os.getpid()) """ True Thread-1 子进程-1 <_MainThread(MainThread, started 60668)> [<_MainThread(MainThread, started 60668)>, <Thread(子进程-1, started 55172)>, <Thread(Thread-2, started 62068)>] 3 61048 666 666 """

join 与 守护线程

守护线程, 等待非守护子线程以及主线程结束之后, 结束

  1. from threading import Thread import time def say_hi(name): print("你滚") time.sleep(2) print(f"{name} say hello") if __name__ == '__main__': t = Thread(target=say_hi, args=("egon",)) # t.setDaemon(True) # 必须在t.start()前设置, 两种方法都可以 t.daemon = True t.start() print("主线程") # 注意 线程的开启速度比进程要快的多 """ 你滚 主线程 """
  2. 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 """

互斥锁

  1. from threading import Thread import time import random x = 100 def task(): 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}') """ 主线程99 """ # 多个任务共抢一个数据, 为了保证数据的安全性, 要让其串行 from threading import Thread from threading import Lock import time x = 100 def task(lock): lock.acquire() global x temp = x temp = temp - 1 x = temp lock.release() if __name__ == '__main__': mutex = Lock() l1 = [] for i in range(100): t = Thread(target=task,args=(mutex,)) l1.append(t) t.start() time.sleep(3) print(f'主线程{x}') """ 主线程0 """

转载于:https://www.cnblogs.com/beichen123/p/11397807.html

发表评论

表情:
评论列表 (有 0 条评论,78人围观)

还没有评论,来说两句吧...

相关阅读

    相关 进程线线

    一、线程与进程 > 一个进程就是一个应用程序,进程包含线程 > 一个进程至少包含一个线程,大部分都是有多条线程在执行任务 > 进程是系统资源分配资源的最小单位

    相关 进程线线

    一.基本概念 \\1、进程(process)\\ 狭义定义:进程就是一段程序的执行过程。 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它

    相关 进程线线

    一、说说概念 1、进程(process) 狭义定义:进程就是一段程序的执行过程。 广义定义:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动