day35——生产者消费者模型、线程
day35
进程:生产者消费者模型
编程思想,模型,设计模式,理论等等,都是交给你一种编程的方法,以后你遇到类似的情况,套用即可
生产者消费者模型的三要素
- 生产者:产生数据的
- 消费者:接收数据做进一步处理的
- 容器:盆(队列)
队列容器起到什么作用?
- 起到缓冲的作用,平衡生产力与消费力,解耦
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'\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()
线程的理论知识
什么是线程
一条流水线的工作流程
进程:在内存中开启一个进程空间,然后将主进程的所有资源数据复制一份,然后调用cpu去执行这些代码
之前的描述不够具体:
开启一个进程:在内存中开启一个进程空间,然后将主进程的所有的资源数据复制一份,然后调用线程去执行代码
进程是最小的资源单位,线程是最小的执行单位

以后你描述开启一个进程:
开启一个进程:进程会在内存中开辟一个进程空间,将主进程的资料数据全部复制一份,线程会执行里面的代码
线程vs进程
- 开启进程的开销非常大,比开启线程的开销大很多
- 开启线程的速度非常快,要快几十倍到上百倍
- 线程与线程之间可以共享数据,进程与进程之间需借助队列等方法实现通信
线程的应用
并发:一个cpu看起来像是同时执行多个任务
单个进程开启三个线程,并发的执行任务
开启三个进程并发的执行任务
文本编辑器:
1、输入文字
2、在屏幕上显示
3、保存在磁盘中
开启多线程就非常好了:数据共享、开销小、速度快
线程没有地位之分,但是一个进程谁在干活?
只是我们自己的意思:我们把执行主程序的线程当作主线程
主线程在执行代码,当结束之后,你得等待其他线程结束之后,才能结束本进程
开启线程的两种方式
# 第一种方式
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, l1, s1):
super().__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("===主线程")
线程vs进程的代码对比
开启速度对比
多线程
from threading import Thread
import time
def task():
print("hello")
if __name__ == '__main__':
start_time = time.time()
# 在主进程下开启线程
t1 = Thread(target=task)
t2 = Thread(target=task)
t1.start()
t2.start()
print("主线程/主进程")
print(time.time() - start_time)
时间:0.0004723072052001953
多进程
from multiprocessing import Process
import time
def work():
print("hellow")
if __name__ == '__main__':
start_time = time.time()
# 在主进程下开启线程
p1 = Process(target=work)
p2 = Process(target=work)
p1.start()
p2.start()
print("主线程/主进程")
print(time.time() - start_time)
时间:0.023804903030395508
对比pid
进程
主进程和每个子进程的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()}")
结果:
==主12832
子进程:14176
主进程:12832
子进程:11756
主进程:12832
线程
只要是在一个进程内,主线程和每个线程都一样
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()}")
结果:
14480
14480
===主线程14480
同一个进程内线程共享内部数据
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}")
线程的相关其他方法(了解)
from threading import Thread
from threading import activeCount
from threading import currentThread
from threading import enumerate
import os
import time
# x = 3
def task():
# print(currentThread()) # 获取当前线程对象
# time.sleep(1)
print(333)
if __name__ == '__main__':
t1 = Thread(target=task, name="线程1")
# t2 = Thread(target=task, name="线程2")
t1.start()
# t1.setName("朱凡宇") # 添加name属性
# print(t1.getName()) # 查看name属性
# print(t1.name) # 查看name属性 ****
# print(t1.isAlive()) # 判断线程是否活着
# threading方法
# print(currentThread()) # 获取当前线程对象
# print(enumerate()) # 返回一个列表,包含所有的线程对象
print(activeCount()) # 返回存活线程的数量 ****
# t2.start()
join与守护进程(考点)
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=("海狗1",))
t2 = Thread(target=task, args=("海狗2",))
t3 = Thread(target=task, args=("海狗3",))
t1.start()
t1.join()
t2.start()
t2.join()
t3.start()
t3.join()
print(f"===主线程{time.time() - start_time}")
结果:
海狗1 is running
海狗1 is gone
海狗2 is running
海狗2 is gone
海狗3 is running
海狗3 is gone
===主线程3.0027503967285156
守护进程
# 守护进程
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=("egon",))
t.daemon = 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))
x = temp -1
if __name__ == '__main__':
l1 = []
for i in range(100):
t = Thread(target=task)
l1.append(t)
t.start()
for i in l1: # 使主线程无法先运行print(f"主线程{x}")
i.join()
print(f"主线程{x}")
结果: 一直是99
解决:
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(random.randint(1, 3))
x = temp -1
lock.release()
if __name__ == '__main__':
mutex = Lock()
l1 = []
for i in range(100):
t = Thread(target=task, args=(mutex,))
l1.append(t)
t.start()
for i in l1: # 使主线程无法先运行print(f"主线程{x}")
i.join()
print(f"主线程{x}")
结果:一直是0
day35——生产者消费者模型、线程的更多相关文章
- 8.12 day31 进程间通信 Queue队列使用 生产者消费者模型 线程理论 创建及对象属性方法 线程互斥锁 守护线程
进程补充 进程通信 要想实现进程间通信,可以用管道或者队列 队列比管道更好用(队列自带管道和锁) 管道和队列的共同特点:数据只有一份,取完就没了 无法重复获取用一份数据 队列特点:先进先出 堆栈特点: ...
- python并发编程-进程间通信-Queue队列使用-生产者消费者模型-线程理论-创建及对象属性方法-线程互斥锁-守护线程-02
目录 进程补充 进程通信前言 Queue队列的基本使用 通过Queue队列实现进程间通信(IPC机制) 生产者消费者模型 以做包子买包子为例实现当包子卖完了停止消费行为 线程 什么是线程 为什么要有线 ...
- 生产者-消费者模型-线程安全队列Queue
#python3 #product new data into the queue #comsume data from the queue from queue import Queue impor ...
- 4、网络并发编程--僵尸进程、孤儿进程、守护进程、互斥锁、消息队列、IPC机制、生产者消费者模型、线程理论与实操
昨日内容回顾 操作系统发展史 1.穿孔卡片 CPU利用率极低 2.联机批处理系统 CPU效率有所提升 3.脱机批处理系统 CPU效率极大提升(现代计算机雏形) 多道技术(单核CPU) 串行:多个任务依 ...
- 第23章 java线程通信——生产者/消费者模型案例
第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...
- python_way ,day11 线程,怎么写一个多线程?,队列,生产者消费者模型,线程锁,缓存(memcache,redis)
python11 1.多线程原理 2.怎么写一个多线程? 3.队列 4.生产者消费者模型 5.线程锁 6.缓存 memcache redis 多线程原理 def f1(arg) print(arg) ...
- Python学习笔记——进阶篇【第九周】———线程、进程、协程篇(队列Queue和生产者消费者模型)
Python之路,进程.线程.协程篇 本节内容 进程.与线程区别 cpu运行原理 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Ev ...
- Java多线程之~~~使用Exchanger在线程之间交换数据[这个结合多线程并行会有解决很多问题]生产者消费者模型
http://blog.csdn.net/a352193394/article/details/39503857 Java多线程之~~~使用Exchanger在线程之间交换数据[这个结合多线程并行会 ...
- 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼
1. 操作系统基本知识,进程,线程 CPU是计算机的核心,承担了所有的计算任务: 操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:那么操作系统是如何进行任务调度的呢? ...
随机推荐
- Python 06 Geany的基本使用2
原文:https://www.cnblogs.com/denny402/p/5096001.html 功能:打开图片 1.下载库 pip install matplotlib 2.编写代码,将代码粘贴 ...
- hhhhh我又双叒进步啦!
虽然说从今天开始短暂的暑假一周假期正式开始,然而第一天我就深感在家有多无聊...所以说还是整天待在学校好丫! 不过,就算在家, 勤奋好学的 我也要认真做题!今天就一鼓作气地把排名刷到了第 50 名!! ...
- 思科 DHCP服务器配置及DHCP中继
思路: 1.配置 DHCP 客户端 确保每个 PC 为 自动获取IP地址的方式: 2.配置 SW1 # 创建 VLAN 10 , 20 # 将相关的端口,放入到对应的 VLAN : # 配置交换机之间 ...
- 第10组 Alpha冲刺(5/6)
链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 学习调用中国天气网API,接近实现天气推送功能 对天气推送的形式进行讨论及重确 ...
- Asp.net MVC 权限验证,以及是否允许匿名访问
public class CheckUserAttribute : ActionFilterAttribute, IAuthorizationFilter { public void OnAuthor ...
- php常用命令
--------------------------------------------------------------- 重启phpservice php-fpm restart ------- ...
- firewall防火墙常用操作
# firewall防火墙常用操作 - 启动```systemctl start firewalld```- 停止```systemctl stop firewalld```- 重启```system ...
- 以太坊公链Geth同步
1.安装所需基础工具 yum update -y && yum install git wget bzip2 vim gcc-c++ ntp epel-release nodejs c ...
- 运维笔记--linux环境提示python: command not found
场景描述: 新部署的容器环境,终端执行python命令,提示没有该命令. 从报错异常可以看出,可能是python环境未安装. 分析思路: 检查python路径: 方式一:type -a python ...
- 运行 puppeteer 报错 chrome: error while loading shared libraries: libpangocairo-1.0.so.0: cannot open shared object file: No such file or directory
运行 puppeteer 报错 chrome: error while loading shared libraries: libpangocairo-1.0.so.0: cannot open sh ...