刘沙河 刘沙河
首页
  • Go语言基础

    • 数据类型
    • 反射
    • Go指针
  • Go语言进阶

    • go泛型
    • go条件编译
    • cgo教程
    • Go协程调度原理及GPM模型
    • Go内存管理
    • Go垃圾回收机制
    • Go语言内存对齐
  • Go语言实现原理

    • channel 实现原理
    • slice 实现原理
    • map 实现原理
    • sync.Mutex 实现原理
    • 乐观锁CAS 实现原理
    • singlefight 实现原理
  • gin框架

    • gin中间件原理
    • gin路由原理
  • gorm

    • GORM介绍和使用
    • GORM_CURD操作指南
  • go测试

    • benchmark基准测试
    • pprof 性能分析
  • python进阶

    • Numpy&Pandas
    • celery分布式任务队列
  • Django

    • Django 常见命令
    • middleware中间件
    • Django缓存系统
    • Django信号系统
    • Django REST Framework
  • Flask

    • Flask基础知识总结
    • Flask-SQLAlchemy
  • 爬虫

    • aiohttp
    • scrapy框架
  • Mysql

    • Mysql存储引擎和索引
    • MySQL主从复制
    • Mysql读写分离
    • 数据库分库分表
    • Mysql锁
    • Mysql事务和MVCC原理
    • 分库分表带来的读扩散问题
  • Redis

    • redis基础和数据类型
    • redis主从架构
    • redis哨兵架构
    • redis集群模式
    • 如何保证缓存和数据库双写一致
    • redis底层数据结构
    • redis分布式锁
  • Elasticsearch

    • es基本概念
    • es基础语法
    • es倒排索引
  • etcd

    • Go操作etcd
    • Raft原理
    • etcd分布式锁
  • kafka

    • 消息队列MQ总结
    • kafka 概述及原理
    • kafka 消费问题记录
    • 零拷贝技术
    • kafka分区规范
  • RabbitMQ

    • rabbitMQ基础
    • Go操作rabbitmq
  • RocketMQ

    • 可靠消息队列 rocketMQ
  • Http&Https

    • http&https
    • TCP和UDP
    • Ping 原理
  • RPC

    • RPC初识
    • grpc初识和实现
  • gRPC

    • grpc 初识
    • grpc 上下文 metadata
    • grpc 健康检查
    • grpc keepalive
    • grpc 命名解析
    • grpc 中间件&拦截器
    • grpc 负载均衡
    • grpc 身份认证
    • grpc 超时重试
    • grpc 链路追踪
    • grpc-gw将gRPC转RESTfu api
    • grpc-gw自定义选项
  • protobuf

    • protobuf 进阶
    • protobuf 编码原理
  • Docker

    • Docker基础
    • Docker常用命令
    • Dockerfile
    • Docker-Compose
    • Docker多阶段构建
    • Docker Config 教程
    • Docker Swarm 教程
    • Docker Stack 教程
    • Docker Buildx 教程
  • k8s

    • k8s 基础概念
    • k8s 集群架构
    • k8s 工作负载
    • Pod 网络
    • Service 网络
    • 外部接入网络
    • 一张图搞懂k8s各种pod
    • k8s 存储抽象
    • mac快速启动k8s
    • 自制申威架构k8s-reloader
  • go-kit

    • go-kit初识
    • go-kit启动http服务
    • go-kit集成gin启动服务
    • go-kit集成grpc和protobuf
    • go-kit中间件
    • go-kit服务注册发现与负载均衡
    • go-kit限流和熔断
    • go-kit链路追踪
    • go-kit集成Prometheus
  • 设计模式

    • 初识设计模式
    • 创建型模式
    • 结构型模式
    • 行为模式
  • 数据结构

    • 时间轮
    • 堆、双向链表、环形队列
    • 队列:优先队列
    • 队列:延迟队列
  • 算法

    • 递归算法
    • 枚举算法
    • 动态规划
    • 回溯算法
    • 分治算法
    • 贪心算法
    • LRU和LFU
    • 一致性哈希

花开半夏,半夏花开
首页
  • Go语言基础

    • 数据类型
    • 反射
    • Go指针
  • Go语言进阶

    • go泛型
    • go条件编译
    • cgo教程
    • Go协程调度原理及GPM模型
    • Go内存管理
    • Go垃圾回收机制
    • Go语言内存对齐
  • Go语言实现原理

    • channel 实现原理
    • slice 实现原理
    • map 实现原理
    • sync.Mutex 实现原理
    • 乐观锁CAS 实现原理
    • singlefight 实现原理
  • gin框架

    • gin中间件原理
    • gin路由原理
  • gorm

    • GORM介绍和使用
    • GORM_CURD操作指南
  • go测试

    • benchmark基准测试
    • pprof 性能分析
  • python进阶

    • Numpy&Pandas
    • celery分布式任务队列
  • Django

    • Django 常见命令
    • middleware中间件
    • Django缓存系统
    • Django信号系统
    • Django REST Framework
  • Flask

    • Flask基础知识总结
    • Flask-SQLAlchemy
  • 爬虫

    • aiohttp
    • scrapy框架
  • Mysql

    • Mysql存储引擎和索引
    • MySQL主从复制
    • Mysql读写分离
    • 数据库分库分表
    • Mysql锁
    • Mysql事务和MVCC原理
    • 分库分表带来的读扩散问题
  • Redis

    • redis基础和数据类型
    • redis主从架构
    • redis哨兵架构
    • redis集群模式
    • 如何保证缓存和数据库双写一致
    • redis底层数据结构
    • redis分布式锁
  • Elasticsearch

    • es基本概念
    • es基础语法
    • es倒排索引
  • etcd

    • Go操作etcd
    • Raft原理
    • etcd分布式锁
  • kafka

    • 消息队列MQ总结
    • kafka 概述及原理
    • kafka 消费问题记录
    • 零拷贝技术
    • kafka分区规范
  • RabbitMQ

    • rabbitMQ基础
    • Go操作rabbitmq
  • RocketMQ

    • 可靠消息队列 rocketMQ
  • Http&Https

    • http&https
    • TCP和UDP
    • Ping 原理
  • RPC

    • RPC初识
    • grpc初识和实现
  • gRPC

    • grpc 初识
    • grpc 上下文 metadata
    • grpc 健康检查
    • grpc keepalive
    • grpc 命名解析
    • grpc 中间件&拦截器
    • grpc 负载均衡
    • grpc 身份认证
    • grpc 超时重试
    • grpc 链路追踪
    • grpc-gw将gRPC转RESTfu api
    • grpc-gw自定义选项
  • protobuf

    • protobuf 进阶
    • protobuf 编码原理
  • Docker

    • Docker基础
    • Docker常用命令
    • Dockerfile
    • Docker-Compose
    • Docker多阶段构建
    • Docker Config 教程
    • Docker Swarm 教程
    • Docker Stack 教程
    • Docker Buildx 教程
  • k8s

    • k8s 基础概念
    • k8s 集群架构
    • k8s 工作负载
    • Pod 网络
    • Service 网络
    • 外部接入网络
    • 一张图搞懂k8s各种pod
    • k8s 存储抽象
    • mac快速启动k8s
    • 自制申威架构k8s-reloader
  • go-kit

    • go-kit初识
    • go-kit启动http服务
    • go-kit集成gin启动服务
    • go-kit集成grpc和protobuf
    • go-kit中间件
    • go-kit服务注册发现与负载均衡
    • go-kit限流和熔断
    • go-kit链路追踪
    • go-kit集成Prometheus
  • 设计模式

    • 初识设计模式
    • 创建型模式
    • 结构型模式
    • 行为模式
  • 数据结构

    • 时间轮
    • 堆、双向链表、环形队列
    • 队列:优先队列
    • 队列:延迟队列
  • 算法

    • 递归算法
    • 枚举算法
    • 动态规划
    • 回溯算法
    • 分治算法
    • 贪心算法
    • LRU和LFU
    • 一致性哈希
  • Python基础

  • Python进阶

  • Python并发编程

    • 并发编程初识
    • 进程
    • Process模块&锁&进程之间通信
      • 0.同步/异步,阻塞/非阻塞-(面试)
      • 1. Process 模块
        • 1.1守护进程
        • 1.2 Process 其他方法
        • 1.3 面向对象 创建子进程
        • Process类汇总
      • 2.锁lock
      • 3.进程之间的通信 IPC
    • 生产者消费者模型
    • 线程-锁&池
    • 协程
  • Django

  • Flask

  • 爬虫

  • Python
  • Python并发编程
bigox
2021-03-22
目录

Process模块&锁&进程之间通信

# 0.同步/异步,阻塞/非阻塞-(面试)

1.涉及到IO操作时

  • 同步,就是发起调用后,被调用者处理消息,必须等处理完才直接返回结果,没处理完之前是不返回的,调用者主动等待结果;
  • 异步,就是发起调用后,被调用者直接返回,但是并没有返回结果,等处理完消息后,通过状态、通知或者回调函数来通知调用者,调用者被动接收结果。

2.涉及到CPU线程调度时

  • 阻塞,就是调用结果返回之前,该执行线程会被挂起,不释放CPU执行权,线程不能做其它事情,只能等待,只有等到调用结果返回了,才能接着往下执行;
  • 非阻塞,就是在没有获取调用结果时,不是一直等待,线程可以往下执行,如果是同步的,通过轮询的方式检查有没有调用结果返回,如果是异步的,会通知回调。

# 1. Process 模块

from multiprocessing import Process

def send_mile(*args):
    print('%s发送完毕'%*args)

if __name__ == '__main__':
    lis=[]
    for i in range(10):
        p = Process(target=send_mile,args=(1,))#args=(1,)1为传进去的参数
        p.start()
        lis.append(p)
    for p in lis:
        p.join()
    print('start异步')
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 1.1守护进程

  • 有一个参数(p.daemon())可以把一个子进程设置为守护进程

    • 守护进程是随着主进程的代码结束而结束的
  • 所有的子进程都必须在主进程结束之前结束,由主进程回收资源

    import os
    import time
    from multiprocessing import Process
    
    def son():
        while True:
            print('start')
            time.sleep(1)
    
    if __name__=='__main__':
        p=Process(target=son)
        p.deamon=True		#把p子进程设置成了一个守护进程
        p.start()
        time.sleep(5)
        print('main:')
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

# 1.2 Process 其他方法

  • start() 开启进程 异步非阻塞

  • is_alive() 进程是否开启

  • terminate() 强制结束一个子进程 异步非阻塞

  • 存在问题:在terminate告诉操作系统关闭子进程时,继续执行下面代码,强制关闭需要时间消耗,在操作系统还没来得及关闭,立即查看该子进程时还是在运行

  • 最好的诠释了什么是异步非阻塞概念

  import time
  from multiprocessing import Process
  
def son1():
      while True:
          print('is alive')
          time.sleep(0.5)
  
  if __name__ == '__main__':
      p = Process(target=son1)
      p.start()      # 异步 非阻塞
      print(p.is_alive())
      time.sleep(1)
      p.terminate()   # 异步 非阻塞
      print(p.is_alive())   # 进程还活着 因为操作系统还没来得及关闭进程
      time.sleep(0.01)
      print(p.is_alive())   # 操作系统已经响应了我们要关闭进程的需求,再去检测的时候,得到的结果是进程已经结束了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#面试...异步非阻塞概念
**1.```涉及到IO操作时```**

- 同步,就是发起调用后,被调用者处理消息,必须等处理完才直接返回结果,没处理完之前是不返回的,调用者主动等待结果;
- 异步,就是发起调用后,被调用者直接返回,但是并没有返回结果,等处理完消息后,通过状态、通知或者回调函数来通知调用者,调用者被动接收结果。

**2.```涉及到CPU线程调度时```**

- 阻塞,就是调用结果返回之前,该执行线程会被挂起,不释放CPU执行权,线程不能做其它事情,只能等待,只有等到调用结果返回了,才能接着往下执行;
- 非阻塞,就是在没有获取调用结果时,不是一直等待,线程可以往下执行,如果是同步的,通过轮询的方式检查有没有调用结果返回,如果是异步的,会通知回调。
1
2
3
4
5
6
7
8
9
10

# 1.3 面向对象 创建子进程

#固定格式
import time
from multiprocessing import Process

class MyProcess(Process):
    def __init__ (self,x,y):
        self.x=x
        self.y=y
        super().__init__()		#传参数时加上super()的init
    def run(self):		#gai方法的名字一定要写成run,不能变
        print(self.x,self.y)
        for i in range(5):
            print('in son1')
            time.sleep(1)

if __name__=='__main__':
    mp = MyProcess(1,2) #传入参数(1,2)
    mp.daemon = True
    mp.start()
    time.sleep(1)
    print(1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# Process类汇总

# Process类
# 开启进程的方式
    # 面向函数
        # def 函数名:要在子进程中执行的代码
        # p = Process(target= 函数名,args=(参数1,))
    # 面向对象
        # class 类名(Process):
            # def __init__(self,参数1,参数2):   # 如果子进程不需要参数可以不写
                # self.a = 参数1
                # self.b = 参数2
                # super().__init__()
            # def run(self):
                # 要在子进程中执行的代码
        # p = 类名(参数1,参数2)
    # Process提供的操作进程的方法
        # p.start() 开启进程      异步非阻塞
        # p.terminate() 结束进程  异步非阻塞

        # p.join()     同步阻塞
        # p.isalive()  获取当前进程的状态

        # daemon = True 设置为守护进程,守护进程永远在主进程的代码结束之后自动结束
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 2.锁lock

with 上下文管理

  • 加锁之后能够保障数据的安全性,降低了代码的执行效率

  • with lock 给缩进下文加锁,与with open 类似,缩进内容结束后自动释放解锁

  • 在主进程中实例化 lock=Lock()

  • 在子进程中,对需要加锁的代码执行 with lock:

  • 加锁应用场景:

    • 操作共享的数据资源(文件,数据库)
    • 对资源进行修改操作
#示例
import time
import json
from multiprocessing import Process,Lock

def buy_ticket(user,lock):
    # with lock:
    # lock.acquire()   # 给这段代码加上一把锁
        time.sleep(0.02)
        with open('ticket_count') as f:
            dic = json.load(f)
            dic['count'] -= 1
    # lock.release()   # 给这段代码解锁

def task(user, lock):
    with lock:				#加锁最佳方式
        buy_ticket(user, lock)

if __name__ == '__main__':
    lock = Lock()
    for i in range(10):
        p = Process(target=task,args=('user%s'%i,lock))#把这把锁传递给子进程
        p.start()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#了解:
with lock 与下面功能相同;
- lock.acquire()   约束,加锁
- lock.release()   释放,解锁
1
2
3
4

# 3.进程之间的通信 IPC

  • 进程之间数据绝对隔离,如果通信肯定是通过文件或者网络实现通信

  • IPC (inter process communication)

  • Queue 模块from multiprocessing import Queue

  • 先进先出

  • .put() 放数据当队列为满的时候,队列会阻塞

  • .get() 取数据 当队列为空时,get会放生阻塞

  • .put_nowait() 放数据:当队列为满时,会报错,丢失数据

  • .get_nowait() 取数据: 当队列为空时,会报错,不阻塞

#基本格式
import queue

from multiprocessing import Queue
q = Queue(5)
q.put(1)

print(q.get())
1
2
3
4
5
6
7
8
  • Queue

    • 使用了文件家族的 socket 和 pickle 模块

    • 为了数据安全,也使用了 lock 模块,天生有锁,安全

    • pipe 管道,天生没锁了解

#Python#
上次更新: 2023/04/16, 18:35:33
进程
生产者消费者模型

← 进程 生产者消费者模型→

最近更新
01
go与http代理
05-24
02
自制申威架构k8s-reloader
12-06
03
Docker Buildx 教程
12-01
更多文章>
Theme by Vdoing | Copyright © 2020-2024 小刘扎扎 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式