同步异步

用来表达任务的提交方式

同步:提交任务之后原地等待任务的返回结果 期间不做任何事

异步:提交任务之后不愿等待任务的返回结果 直接去做其他事 有结果自动通知

eg:

​ 同步:客户端发送请求给服务端,在等待服务端响应的请求时,客户端不做其他的事情。当服务端做完了才返回到客户端。这样的话客户端需要一直等待

​ 异步:当客户端发送给服务端请求时,在等待服务端响应的时候,客户端可以做其他的事情,这样节约了时间,提高了效率

阻塞与非阻塞

用来表达任务的执行状态

阻塞和非阻塞这两个概念与程序(线程)等待消息通知(无所谓同步或者异步)时的状态有关 也就是说阻塞与非阻塞主要是程序(线程)等待消息通知时的角度来说的

阻塞:阻塞态

非阻塞:就绪态、运行态

综合使用

同步阻塞:效率最低 你一直在原地专心等待啥事也不干

异步阻塞:异步操作是可以被阻塞的 只不过他不是在处理消息时阻塞 而是在等待消息通知时被阻塞

同步非阻塞:需要在这两种不同的行为之间来回切换 效率低下

异步非阻塞:效率最高

总结:阻塞和非阻塞描述的是程序在等待调用结果(消息 返回值)时的状态;同步和异步描述的是消息通信的机制

创建进程的多种方式之multiprocess.process模块

'''
1.鼠标双击软件图标
2.python代码创建进程
'''
multiprocess.process模块
process模块是一个创建进程的模块 from multiprocessing import Process
import time def task():
print('task is running')
time.sleep(3)
print('task is over') p1 = Process(target=task)
p1.start()
print('主进程')
'''
在不同操作系统中穿创建进程底层原理不一样
windows
以导入模块的形式创建进程
linux/mac
以拷贝代码的形式创建进程
'''

方式一

from multiprocessing import Process
import time def task(name):
print('task is running', name)
time.sleep(3)
print('task is over', name) if __name__ == '__main__':
# p1 = Process(target=task, args=('jason',)) # 位置参数
p1 = Process(target=task, kwargs={'name': 'jason'}) # 关键字参数 p1.start() # 异步 告诉操作系统创建一个新的进程 并在该进程中执行task函数
print('主进程')

方式二

from multiprocessing import Process
import time class MyProcess(Process):
def run(self):
print('run is running')
time.sleep(3)
print('run is over') if __name__ == '__main__':
obj = MyProcess()
obj.start()
print('我是主进程的') # 传参
from multiprocessing import Process
import time class MyProcess(Process):
def __init__(self, name, age): # 传值需要从新重写双下init方法
super().__init__() # 这里init括号不传参是因为 父类init里面的形参全是默认参数 需注意super所放的位置
self.name = name # 这里的self是进程对象 给新产生的进程对象新增两个对象独有的属性name、age
self.age = age
# super().__init__() def run(self):
print('run is running', self.name, self.age)
time.sleep(3)
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 = 10000 def task():
global money
money = 888
print('子进程的task函数查看money', money) if __name__ == '__main__':
p1 = Process(target=task)
p1.start()
time.sleep(3)
print(money)

上面我们看到,在windows中创建进程是相当于导模块的操作,因此可以看成子进程的代码相当于在另外一个py文件中执行,虽然用上了global改变全局变量,因为跟主进程不在一个文件,可以看成产生了数据隔离

进程的join方法

from multiprocessing import Process
import time def task(name):
print('%s is running' % name)
time.sleep(3)
print('%s is over' % name) if __name__ == '__main__':
P = Process(target=task, args=('jason',))
P.start() # 异步
P.join() # 主进程代码等待子进程代码运行结束再执行
print('我是主进程的') # 这样主进程的永远都是最后打印 # 变形
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))
start_time = time.time()
p1.start() # 主进程同时创建了3个子进程P1 P2 P3 在第一个P1进程执行时 时间为1秒 那么其他子进程P2 P3异步也执行了1秒 同理到在P2子进程时执行2秒 P3也执行了2秒了
# p1.join()
p2.start()
# p2.join()
p3.start()
# p3.join() # 按顺序的话就是一个个来轮流执行 时间6秒多
p1.join()
p2.join()
p3.join()
print(time.time() - start_time) # 3秒多 打印结果:
jason1 is running
jason2 is running
jason3 is running
jason1 is over
jason2 is over
jason3 is over
3.097902297973633

IPC机制

IPC:进程间通信
消息队列:储存数据的地方 所有人都可以存 也都可以取
from mutiprocessing import Queue q = Queue(3) # 括号内可以指定存储数据的个数
q.put(999) # 往队列里存放数据
q.put(666)
q.put(888)
print(q.full()) # True 判断队列是否已满 print(q.get()) # 999 从消息队列中取数据 按照先进先出取值 print(q.empty()) # Flase 判断队列里是否为空 from multiprocessing import Process,Queue
def product(q):
q.put('子进程获取队列中的数据', q.get())

full() empty() 在多进程中都不能使用


from multiprocessing import Process, Queue def product(q):
q.put('子进程p添加的数据') def consumer(q):
print('子进程获取队列中的数据', q.get()) if __name__ == '__main__':
q = Queue()
# 主进程往队列中添加数据
# q.put('我是主进程添加的数据')
p1 = Process(target=consumer, args=(q,))
p2 = Process(target=product, args=(q,))
p1.start()
p2.start()
print('我是主进程')

生产者 消费者模型

1.生产者

​ 负责生产数据的人

2.消费者

​ 负责处理数据的人

该模型除了有生产者和消费者之外还必须有消息队列(只有能够提供数据保存服务和提取服务的理论上都可以)

进程对象的多种方法

1.如何查看进程号

方式一
from multiprocessing import Process, current_process def task():
print(current_process())
print(current_process().pid) # 获取当前进程的进程 if __name__ == '__main__':
p = Process(target=task)
p.start()
print(current_process())
print(current_process().pid) # 获取当前进程的进程 方式二
from multiprocessing import Process
import os def task():
print('我是子进程', os.getpid()) # 我是子进程 34604 if __name__ == '__main__':
p = Process(target=task)
p.start()
print('我是主进程', os.getpid()) # 我是主进程 40604
print('我是pycharm进程编号', os.getppid) # 我是pycharm进程编号 33528 获取主进程的父进程

2.终止进程

from multiprocessing import Process, current_process
import time def task():
print('子进程',current_process().pid) # 获取当前进程的进程 if __name__ == '__main__':
p = Process(target=task)
p.start()
# time.sleep(0.1)
p.terminate() # 终止p子进程 也是异步操作
print('主进程', current_process().pid) # 获取当前进程的进程



3.判断进程是否存活

from multiprocessing import Process, current_process
import time def task():
print('子进程',current_process().pid) # 获取当前进程的进程 if __name__ == '__main__':
p = Process(target=task)
p.start()
# p.terminate()
print(p.is_alive()) # 判断子进程是否存活
# time.sleep(0.1)
# p.terminate() # 终止p子进程 也是异步操作
print('主进程', current_process().pid) # 获取当前进程的进程

守护进程

主进程创建守护进程

  其一:守护进程会在主进程代码执行结束后就终止

  其二:守护进程内无法再开启子进程,否则抛出异常:

AssertionError: daemonic processes are not allowed to have children

注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止

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

僵尸进程与孤儿进程

僵尸进程
进程执行完毕后并不会立刻销毁所有的数据 会有一些信息短暂保留下来‘
比如进程号、进程执行时间、进程消耗功率等给父进程查看
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.randint(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(10):
p = Process(target=run, args=('用户%s'%i, ))
p.start() """
多进程操作数据很可能会造成数据错乱>>>:互斥锁
互斥锁
将并发变成串行 牺牲了效率但是保障了数据的安全
"""

同步异步、mutiprocessing创建进程process模块及进程对象的多种方法、消息队列Queue的更多相关文章

  1. 第三十天- 进程 Process模块 空间隔离

    1.进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实体: ...

  2. python中datetime模块中datetime对象的使用方法

    本文只讲述datetime模块中datetime对象的一些常用的方法,如果读者需要更多datetime模块的信息,请查阅此文档. datetime模块的对象有如下: timedelta date da ...

  3. GCD,用同步/异步函数,创建并发/串行队列

    队列  第一个参数:C语言字符串,标签 第二个参数: DISPATCH_QUEUE_CONCURRENT:并发队列 DISPATCH_QUEUE_SERIAL:串行队列 dispatch_queue_ ...

  4. 鸿蒙内核源码分析(消息队列篇) | 进程间如何异步传递大数据 | 百篇博客分析OpenHarmony源码 | v33.02

    百篇博客系列篇.本篇为: v33.xx 鸿蒙内核源码分析(消息队列篇) | 进程间如何异步传递大数据 | 51.c.h .o 进程通讯相关篇为: v26.xx 鸿蒙内核源码分析(自旋锁篇) | 自旋锁 ...

  5. C# ABP - 创建自己的模块

    本篇文章介绍怎么创建自己的模块,并且使用依赖注入方法进行模块间的无缝结合. 我们创建一下自己的一个会员模块,针对不同的系统都可以用.你们可以看看我是怎么做的,或者从中得到启发. 目录 1.开始创建项目 ...

  6. python---基础知识回顾(十)进程和线程(进程)

    前戏:进程和线程的概念 若是学过linux下的进程,线程,信号...会有更加深刻的了解.所以推荐去学习下,包括网络编程都可以去了解,尤其是对select,poll,epoll都会有更多的认识. 进程就 ...

  7. 8.7 进程间的通讯:管道、消息队列、共享内存、信号量、信号、Socket

    进程间的通讯 进程间为什么需要通讯? 共享数据.数据传输.消息通知.进程控制 进程间的通讯有哪些类型? 首先,联系前面讲过的知识,进程之间的用户地址空间是相互独立的,不能进行互相访问,但是,内核空间却 ...

  8. linux 进程学习笔记-消息队列messagequeue

    可以想象,如果两个进程都可以访问同一个队列:其中一个进程(sender)向其中写入结构化数据,另外一个进程(receiver)再从其中把结构化的数据读取出来.那么这两个进程就是在利用这个队列进行通信了 ...

  9. day43-python消息队列二-queue模块

    Python提供了Queue模块来专门实现消息队列Queue对象 Queue对象实现一个fifo队列(其他的还有lifo.priority队列,这里不再介绍).queue只有maxsize一个构造参数 ...

  10. {Python之进程} 背景知识 什么是进程 进程调度 并发与并行 同步\异步\阻塞\非阻塞 进程的创建与结束 multiprocess模块 进程池和mutiprocess.Poll

    Python之进程 进程 本节目录 一 背景知识 二 什么是进程 三 进程调度 四 并发与并行 五 同步\异步\阻塞\非阻塞 六 进程的创建与结束 七 multiprocess模块 八 进程池和mut ...

随机推荐

  1. 新电脑搭建vue项目步凑

    电脑必备软件集合: Chrome,FF Nodejs VS code (ATOM...) GIT || SVN 插件类:postman 美术类:ps,pxcock等,自己喜欢的就行 翻译类:有道词典 ...

  2. 关于将Azure云上磁盘导出-使用VirtualBox转换成vmdk格式的方法记录

    在工作中,经常会遇到虚拟磁盘文件格式的转换需求,尤其是在虚拟化迁移及云环境迁移到DC的虚拟化环境中 或者中转处理,如最近笔者遇到一个需要将Azure Cloud上的磁盘导出到VMware中,但Azur ...

  3. 洛谷P4147 玉蟾宫 (单调栈)

    要求我们去找一个最大矩形面积. 单调栈做法(和P1950 长方形那道题类似(一模一样)). 1 #include<bits/stdc++.h> 2 using namespace std; ...

  4. 京东云TiDB SQL优化的最佳实践

    京东云TiDB SQL层的背景介绍 从总体上概括 TiDB 和 MySQL 兼容策略,如下表: SQL层的架构 用户的 SQL 请求会直接或者通过 Load Balancer 发送到 京东云TiDB ...

  5. Vue3.x+element-plus+ts踩坑笔记

    闲聊 前段时间小颖在B站找了个学习vue3+TS的视频,自己尝试着搭建了一些基础代码,在实现功能的过程中遇到了一些问题,为了防止自己遗忘,写个随笔记录一下嘻嘻 项目代码 git地址:vue3.x-ts ...

  6. 生成随机数的几种方法、Math.random()随机数的生成、Random()的使用

    第一种方法使用:System.currentTimeMillis(); final long l = System.currentTimeMillis(); final int rs = (int) ...

  7. 设计模式常用的UML图------类图

    关系 UML将事物之间的联系归纳为6种,对应响应的图形 关联 定义:表示拥有的关系,具有方向性,一个类单向访问一个类,为单向关联.两个类可以相互访问,为双向关联. 聚合 定义:整体与部分的关系. 组合 ...

  8. NLP之基于词嵌入(WordVec)的嵌入矩阵生成并可视化

    词嵌入 @ 目录 词嵌入 1.理论 1.1 为什么使用词嵌入? 1.2 词嵌入的类比推理 1.3 学习词嵌入 1.4 Word2Vec & Skip-Gram(跳字模型) 1.5 分级& ...

  9. 常用排序算法(C语言)

    1.冒泡排序 void BubbleSort(int a[],int len) {int tmp; for (int i=0; i<n-1; i++) { int flag = FALSE; f ...

  10. LcdToos如何在线调屏PORCH参数

    在点屏过程中,我们会经常碰到画面对不齐现象,在这种情况下需要多次尝试修调屏的PORCH参数来使画面显示正常:通常的做法是修改完PORCH参数下载到PG,点亮看效果,这种方法无疑效率很低,对于现象的表现 ...