同步与异步

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

阻塞与非阻塞

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

总结

同步阻塞
同步非阻塞
异步阻塞
异步非阻塞(******)
效率最高 同步、异步,与阻塞、非阻塞不相关。
同步、异步强调的是结果。
阻塞和非阻塞强调的是时间,是否等待。
同步与异步区别在于:调用者是否得到了想要的最终结果。 同步就是一直要执行到返回最终结果。 异步就是直接返回了,但是返回的不是最终的结果,调用者不能通过这种调用得到结果,还要通过被调用者,使用其他方式通知调用者,来取回最终结果。 阻塞与非阻塞的区别在于,调用者是否还能干其他的事情。 阻塞,调用者只能干等。 非阻塞,调用者可以先忙一会别的,不用一直等。 联系: 同步阻塞:调用者阻塞,直到等到拿到最终结果。(打饭模型,什么事情也不敢,就等着打饭,打饭是结果,什么也不干,一直在等着,同步加阻塞) 同步非阻塞:(等着打饭,但是可以玩会手机,看看电视,打饭是结果,但是不用一直在等着) 异步阻塞:(我要打饭,你说等着较好,并没有返回饭给我,我啥事不干,就干等着饭好了叫我) 异步非阻塞:回调的话。(我要打饭,你说等较好,并没有返回饭给我,可以在旁边看看电视,玩玩手机,饭好了叫我) 同步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. Linux、Windows下Redis的安装即Redis的基本使用详解

    前言 什么是Redis Redis是一个基于内存的key-value结构数据库.Redis 是互联网技术领域使用最为广泛的存储中间件,它是「Remote Dictionary Service」的首字母 ...

  2. vue项目Eslint和prettier结合使用

    一.eslint介绍--代码语法检查工具 Eslint是一个代码检查工具,用来检查你的代码语法是否符合指定的规范,ECMAScript标准 二.prettier插件--代码格式化工具 prettier ...

  3. 使用thymeleaf将查询的数据显示在前台。通过使用循环的形式

    1.需要注意的点. 在 <tr th:each="book:${bookList}">中.book是自己命令的变量.${bookList}是将查询的数据放入这里,需要后 ...

  4. Springboot+Vue实现将图片和表单一起提交到后端,同时将图片地址保存到数据库、再次将存储的图片展示到前端vue页面

    文章目录 1.实现的效果 2.Vue前端 3.图片上传 4.字段变量根据自己的字段名自行设置(这里不给出了,哈哈哈) 5.method方法 5.1.图片显示在选择框中,同时返回后端存储的地址 5.2查 ...

  5. k8s机器群扩容问题

    今天遇到了一个很奇葩的问题.公司新人吧k8s集权扩容完后,发现服务器上的磁盘没有做分区2T磁盘没有做任何动作 把两台slave节点扩容上去的节点弄到了/目录.由于是生产环境情况比较特殊并没通过kube ...

  6. Scrapy 如何传递 get请求的params

    我们都知道 在requests中可以使用 requests.get(url,params)的方式传值 那么在scrapy中如何传值呢 直接看代码 from urllib.parse import ur ...

  7. ES6 学习笔记(十二)代理器Proxy的简单使用

    1.前言 以前在学习react时做了个仿手机端的QQ音乐项目.当时的数据是通过proxy代理的QQ音乐数据接口,直接写在package.json里面.Proxy 对象(Proxy)是 ES6的特性,只 ...

  8. 安装 TypeScript 并编译成JS

    官网: https://github.com/microsoft/TypeScript TypeScript是一种由微软开发的开源.跨平台的编程语言.它是JavaScript的超集,最终会被编译为Ja ...

  9. 读 Clean Code,关于变量命名和可维护代码

    原文见 http://mindprod.com/jgloss/unmain.html 如何写出不能维护的代码 如何程序命名 容易输入的名字.比如:Fred,asdf 单字母的变量名.比如:a,b,c, ...

  10. PyQt5程序打包出错Failed to execute script

    出现这种报错一般有两种可能: 1. 该被引入的资源你没有放到 exe 的相对路径 这种错误一般是你直接引入图片或者图标, 而没有放到 打包后的exe的相对路径 2. 加参数 假设 main.py 为程 ...