同步与异步

用来表达任务的提交方式
同步
提交完任务之后原地等待任务的返回结果 期间不做任何事
异步
提交完任务之后不原地等待任务的返回结果 直接去做其他事 有结果自动通知

阻塞与非阻塞

用来表达任务的执行状态
阻塞
阻塞态
非阻塞
就绪态、运行态

总结

同步阻塞
同步非阻塞
异步阻塞
异步非阻塞(******)
效率最高 同步、异步,与阻塞、非阻塞不相关。
同步、异步强调的是结果。
阻塞和非阻塞强调的是时间,是否等待。
同步与异步区别在于:调用者是否得到了想要的最终结果。 同步就是一直要执行到返回最终结果。 异步就是直接返回了,但是返回的不是最终的结果,调用者不能通过这种调用得到结果,还要通过被调用者,使用其他方式通知调用者,来取回最终结果。 阻塞与非阻塞的区别在于,调用者是否还能干其他的事情。 阻塞,调用者只能干等。 非阻塞,调用者可以先忙一会别的,不用一直等。 联系: 同步阻塞:调用者阻塞,直到等到拿到最终结果。(打饭模型,什么事情也不敢,就等着打饭,打饭是结果,什么也不干,一直在等着,同步加阻塞) 同步非阻塞:(等着打饭,但是可以玩会手机,看看电视,打饭是结果,但是不用一直在等着) 异步阻塞:(我要打饭,你说等着较好,并没有返回饭给我,我啥事不干,就干等着饭好了叫我) 异步非阻塞:回调的话。(我要打饭,你说等较好,并没有返回饭给我,可以在旁边看看电视,玩玩手机,饭好了叫我) 同步IO、异步IO、IO多路复用 IO模型: IO分为两个阶段。 1)数据准备阶段。 2)内核空间复制回用户进程缓冲区阶段。 发生IO的时候: 1、内核从输入设备读、写数据(淘米,把米放锅里煮饭) 2、进程从内核复制数据(盛饭,从内核这个锅把饭装到碗里面来)

创建进程的两种方式

"""
1.鼠标双击软件图标
2.python代码创建进程
"""
1、利用函数创建
from multiprocessing import Process
import time def task(name):
print('task is running',name)
time.sleep(1)
print('task is over', name)
if __name__ == '__main__':
p1 = Process(target=task,args=('jason',)) # 位置参数
# p1 = Process(target=task,kwargs={'name':'jason123'}) # 关键字参数
p1.start() # 异步 告诉操作系统创建一个新的进程 并在该进程中执行task函数
# task() # 同步
print('主程序')
"""
在不同的操作系统中 创建进程底层原理不一样
windows
以导入模块的形式创建进程
linux/mac
以拷贝代码的形式创建进程
""" 2、利用类创建
from multiprocessing import Process
import time class MyProcess(Process):
def __init__(self,name,age):
super().__init__()
self.name = name
self.age = age def run(self):
print('run is running',self.name, self.age)
time.sleep(2)
print('run is over', self.name, self.age) if __name__ == '__main__':
obj = MyProcess('jason',123)
obj.start()
print('主程序')

进程间数据间隔

同一台计算机上的多个进程数据是严格意义上的物理隔离(默认情况下)
from multiprocessing import Process
import time money = 1000 def task():
global money
money = 666
print('子进程的task函数产看money', money)
if __name__ == '__main__':
p1 = Process(target=task)
p1.start() # 创建子进程
time.sleep(2) # 主进程代码等待2秒
print(money) # 主进程代码打印money

进程的join方法

主进程代码等待子进程代码执行完毕 再执行主进程代码

from multiprocessing import Process
import time def task(name,n):
print('%s is running' % name)
time.sleep(n)
print('%s is over' % name) if __name__ == '__main__':
p1 = Process(target=task,args=('jason1',1))
p2 = Process(target=task,args=('jason2',2))
p3 = Process(target=task,args=('jason3',3))
# p1.start() # 异步
# p1.join()
# print('主程序')
stat_time = time.time()
p1.start()
p1.join()
p2.start()
p2.join()
p3.start()
p3.join()
# p1.join()
# p2.join()
# p3.join()
print(time.time() - stat_time) # 6秒多

IPC机制

IPC:进程间通信
消息队列:存储数据的地方 所有人都可以存 也都可以取
from multiprocessing import Queue q = Queue(3) # 括号内可以指定存储数据的个数
# 往消息队列中存放数据
q.put(111)
print(q.full()) # 判断消息队列是否已满
q.put(222)
q.put(333)
print(q.full()) # 判断消息队列是否已满
# 从消息队列中取数据
print(q.get())
print(q.get())
print(q.empty()) # 判断队列是否为空
print(q.get())
print(q.empty()) # 判断队列是否为空
print(q.get()) # 取数据 无数据会原地等待
# print(q.get_nowait()) # 也是取数据 但是如果队列里面没有数据会报错 '''full() empty() 在多进程中都不能使用!!!!'''
from multiprocessing import Process, Queue def producer(q):
q.put('子进程q添加的数据') def consumer(q):
print('子进程获取队列中的数据', q.get()) if __name__ == '__main__':
q = Queue()
# 主进程往队列中添加数据
q.put('我是主进程添加的数据')
p1 = Process(target=consumer, args=(q,))
# p2 = Process(target=producer, args=(q,))
p1.start()
# p2.start()
print('主进程')

生产者消费者模型

生成者
负责产生数据的'人'
消费者
负责处理数据的'人'
该模型除了有生产者和消费者之外还必须有消息队列(只要是能够提供数据保存服务和提取服务的理论上都可以) 生产者消费者模型
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。 为什么要使用生产者和消费者模式
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。 什么是生产者消费者模式
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

进程对象的多种方法

1.如何查看进程号
from multiprocessing import Process,current_process
current_process()
print(current_process().pid)
import os print(os.getpid())
print(os.getppid())
2.终止进程
p1.terminate()
ps:计算机操作系统都有对应的命令可以直接杀死进程
3.判断进程是否存活
p1.is_alive()
5.start() 创建进程
6.join() 阻塞等待进程

守护进程

守护进程会随着守护的进程结束而立刻结束
eg: A是B的守护进程 一旦B嗝屁了 A立刻嗝屁
from multiprocessing import Process
import time def task(name):
print('德邦总管: %s' % name)
time.sleep(2)
print('德邦总管: %s' % name) if __name__ == '__main__':
p1 = Process(target=task, args=('B',))
p1.daemon = True
p1.start()
time.sleep(1)
print('恕瑞玛皇帝: A嗝屁了')

僵尸进程与孤儿进程

僵尸进程
进程执行完毕后并不会立刻销毁所有的数据 会有一些信息短暂保留下来
比如进程号、进程执行时间、进程消耗功率等给父进程查看
ps:所有的进程都会变成僵尸进程
孤儿进程
子进程正常运行 父进程意外死亡 操作系统针对孤儿进程会派遣福利院管理

多进程数据错乱问题

模拟抢票软件
from multiprocessing import Process
import time
import json
import random # 查票
def search(name):
with open(r'data.json','r',encoding='utf8')as f:
data = json.load(f)
print('%s在查票 当前余票为:%s' % (name, data.get('ticket_num'))) # 买票
def buy(name):
# 再次确认票
with open(r'data.json', 'r', encoding='utf8')as f:
data = json.load(f)
# 模拟网络延迟
time.sleep(random.randrange(1, 3))
# 判断是否有票 有就买
if data.get('ticket_num') > 0:
data['ticket_num'] -= 1
with open(r'data.json', 'w', encoding='utf8')as f:
json.dump(data,f)
print('%s买票成功' % name)
else:
print('%s很倒霉,没有抢到票' % name) def run(name):
search(name)
buy(name) if __name__ == '__main__':
for i in range(1,11):
p = Process(target=run, args=('用户%s' % i,))
p.start() """
多进程操作数据很肯会造成数据错乱>>>:互斥锁
互斥锁
将并发变成串行 牺牲了效率但是保障了数据的安全
""" # 加锁之后的代码 from multiprocessing import Process,Lock
import time
import json
import random def search(name):
with open(r'data.json','r',encoding='utf8')as f:
data = json.load(f)
print('%s查看票 目前剩余:%s' % (name, data.get('ticket_num'))) def buy(name):
# 先查询票数
with open(r'data.json','r',encoding='utf8')as f:
data = json.load(f)
# 模拟网络延迟
time.sleep(random.randint(1,3))
# 买票
if data.get('ticket_num') > 0:
with open(r'data.json', 'w',encoding='utf8')as f:
data['ticket_num'] -= 1
json.dump(data,f)
print('%s 买票成功' % name)
else:
print('%s 买票失败 非常可乐 没车回去了'% name)
def run(name,mutex):
search(name)
mutex.acquire() # 抢锁
buy(name)
mutex.release() # 释放锁 if __name__ == '__main__':
mutex = Lock() # 产生一把锁
for i in range(10):
p = Process(target=run, args=('用户%s号' % i,mutex))
p.start() """
锁有很多种 但是作用都一样
行锁 表锁。。。。
"""

python31 网络并发编程方法的更多相关文章

  1. 2、网络并发编程--套接字编程、黏包问题、struct模块、制作简易报头、上传文件数据

    昨日内容回顾 面向对象复习(json序列化类) 对象.类.父类的概念 三大特性:封装 继承 多态 双下开头的方法(达到某个条件自动触发) __init__:对象实例化自动触发 __str__:对象执行 ...

  2. 1、网络并发编程--简介、软件开发架构、OSI七层协议

    python复习 变量与常量 基本数据类型 内置方法 字符编码.文件操作 函数 函数参数.闭包函数.装饰器 面向对象 封装.继承.多态 """ 什么是对象 数据与功能的结 ...

  3. 3、网络并发编程--udp代码、操作系统发展史、多道技术、进程理论

    昨日内容回顾 socket基本使用 # 内置的模块 import socket s = socket.socket() # 默认是TCP协议 也可以切换为UDP协议 s.bind((ip,port)) ...

  4. python之路32 网络并发线程方法 线程池 协程

    多进程实现TCP服务端并发 服务端: import socket from multiprocessing import Process def get_server(): server = sock ...

  5. 4、网络并发编程--僵尸进程、孤儿进程、守护进程、互斥锁、消息队列、IPC机制、生产者消费者模型、线程理论与实操

    昨日内容回顾 操作系统发展史 1.穿孔卡片 CPU利用率极低 2.联机批处理系统 CPU效率有所提升 3.脱机批处理系统 CPU效率极大提升(现代计算机雏形) 多道技术(单核CPU) 串行:多个任务依 ...

  6. 【转】高性能网络编程5--IO复用与并发编程

    对于服务器的并发处理能力,我们需要的是:每一毫秒服务器都能及时处理这一毫秒内收到的数百个不同TCP连接上的报文,与此同时,可能服务器上还有数以十万计的最近几秒没有收发任何报文的相对不活跃连接.同时处理 ...

  7. 03并发编程(多道技术+进程理论+进程join方法)

    目录 03 并发编程 03 并发编程

  8. 【Java并发编程实战】-----“J.U.C”:ReentrantLock之三unlock方法分析

    前篇博客LZ已经分析了ReentrantLock的lock()实现过程,我们了解到lock实现机制有公平锁和非公平锁,两者的主要区别在于公平锁要按照CLH队列等待获取锁,而非公平锁无视CLH队列直接获 ...

  9. Java并发编程(一) 两种实现多线程的方法(Thread,Runnable)

    Java中实现多线程的方法有两种: 继承Thread类和实现Runnable方法,并重写Run方法,然后调用start()方法启动线程.使用Runnable会比Thread要好很多,主要是以下三个原因 ...

随机推荐

  1. IDEA插件MyBatisCodeHelper-Pro的破解与使用

    0.前言 本文中的IDEA版本是2020.3,使用的插件版本是MyBatisCodeHelper-Pro 2.8.9,3.0+版本目前没找到激活的方式 和本文插件类似的还有mybatisX,但我不喜欢 ...

  2. Vue学习之--------深入理解Vuex、原理详解、实战应用(2022/9/1)

    @ 目录 1.概念 2.何时使用? 3.搭建vuex环境 3.1 创建文件:src/store/index.js 3.2 在main.js中创建vm时传入store配置项 4.基本使用 4.1.初始化 ...

  3. 4.websocket基本概念

    websockey的模式就是在于当前端向后端发送请求创建一个websocket链连接之后,连接默认不断开,前端和服务端就维护了一个连接,前端可以通过连接给服务端发消息,服务端也可以通过连接给前端发消息 ...

  4. 1.-Django项目结构

    一.Django简介 Django是一个开放源代码的Web应用框架,由Python写成.采用了MTV的框架模式,即模型M,视图V和模版T.   Django基本组件: 1.基本配置文件/路由系统 2. ...

  5. 七、kubernetes污点和容忍

    Kubernetes污点和容忍 一.Taint 和 Toleration介绍 节点亲和性,是 pod 的一种属性(偏好或硬性要求),它使 pod 被吸引到一类特定的节点.Taint 则相反,它使节点能 ...

  6. shell实践

    shell实践 父子shell 父shell:我们在登录某个虚拟机控制器终端的时候(连接某一个linux虚拟机)时,默认启动的交互式shell,然后等待命令输入. ps命令参数,是否有横杠的参数作用是 ...

  7. 前端学习笔记--HTML5

    网页的优点(客户端为网页)(B/S)模式 开发成本低) 不需要安装 无需更新 跨平台(最重要)可以有效的减小开发成本 传统的为C/S模式,开发成本高 前端工程师负责写网页的源代码,而浏览器负责把网页渲 ...

  8. dockerNginx代理本地目录

    dockerNginx代理本地目录 ssl_certificate cert/5900588_test.zk.limengkai.work.pem; ssl_certificate_key cert/ ...

  9. Nginx如何配置隐藏index.php文件

    server { listen 80; #listen [::]:80 default_server ipv6only=on; server_name jiqing.dexin.com; index ...

  10. 谈软件-专家谈C/C++重构的操作与思路

    1.Refactoring: 对软件内部结构的一种调整,目的是不该被软件的可观察行为的前提上,提高其可理解性,降低其修改成本. 2.代码坏味道 2.1.不易复用 2.2.不易理解 2.3.存在冗余 3 ...