进程同步multiprocess.Lock

我们千方百计实现了程序的异步,让多个任务可以同时在几个进程中并发处理,他们之间的运行没有顺序,一旦开启也不受我们控制。尽管并发编程让我们能更加充分的利用IO资源,但是也给我们带来了新的问题:当多个进程使用同一份数据资源的时候,就会引发数据安全或顺序混乱问题。

一、多进程抢占输出资源

import os
import time
import random
from multiprocessing import Process def work(n):
print('%s: %s is running' %(n,os.getpid()))
time.sleep(random.random())
print('%s:%s is done' %(n,os.getpid())) if __name__ == '__main__':
for i in range(3):
p=Process(target=work,args=(i,))
p.start()

0: 46160 is done

1: 56236 is running

0: 46160 is running

2: 53824 is running

1: 56236 is done

2: 53824 is done

二、使用锁维护执行顺序

import os
import time
import random
from multiprocessing import Process,Lock def work(lock,n):
lock.acquire() # 锁住
print('%s: %s is running' % (n, os.getpid()))
time.sleep(random.random())
print('%s: %s is done' % (n, os.getpid()))
lock.release() # 释放锁头
if __name__ == '__main__':
lock=Lock() # 写在主进程是为了让子进程拿到同一把锁.
for i in range(3):
p=Process(target=work,args=(lock,i))
p.start()
# p.join()
"""
进程锁 是把锁住的代码变成了串行
join 是把所有的子进程变成了串行
为了保证数据的安全,串行牺牲掉效率.
"""

0: 46160 is running

0: 46160 is done

1: 56236 is running

1: 56236 is done

2: 53824 is running

2: 53824 is done

上面这种情况虽然使用加锁的形式实现了顺序的执行,但是程序又重新变成串行了,这样确实会浪费了时间,却保证了数据的安全。接下来,我们以模拟抢票为例,来看看数据安全的重要性。

三、多进程同时抢购余票

# 文件db的内容为:{"count":1}
# 注意一定要用双引号,不然json无法识别
# 并发运行,效率高,但竞争写同一文件,数据写入错乱
from multiprocessing import Process,Lock
import time,json,random
def search():
dic=json.load(open('db'))
print('剩余票数%s' %dic['count']) def get():
dic=json.load(open('db'))
time.sleep(0.1) # 模拟读数据的网络延迟
if dic['count'] >0:
dic['count']-=1
time.sleep(0.2) # 模拟写数据的网络延迟
json.dump(dic,open('db','w'))
print('购票成功') def task():
search()
get() if __name__ == '__main__':
for i in range(10): # 模拟并发100个客户端抢票
p=Process(target=task)
p.start()

剩余票数3

剩余票数3

剩余票数3

剩余票数3

剩余票数3

剩余票数3

剩余票数3

剩余票数3

剩余票数3

剩余票数3

购票成功

购票成功

购票成功

购票成功

购票成功

购票成功

购票成功

购票成功

购票成功

购票成功

四、使用锁来保证数据安全

# 文件db的内容为:{"count":2}
# 注意一定要用双引号,不然json无法识别
# 并发运行,效率高,但竞争写同一文件,数据写入错乱
from multiprocessing import Process,Lock
import time,json,random
def search():
dic=json.load(open('db'))
print('剩余票数%s' %dic['count']) def get():
dic=json.load(open('db'))
time.sleep(random.random()) # 模拟读数据的网络延迟
if dic['count'] >0:
dic['count']-=1
time.sleep(random.random()) # 模拟写数据的网络延迟
json.dump(dic,open('db','w'))
print('购票成功')
else:
print('购票失败') def task(lock):
search()
lock.acquire()
get()
lock.release() if __name__ == '__main__':
lock = Lock()
for i in range(100): # 模拟并发100个客户端抢票
p=Process(target=task,args=(lock,))
p.start()

剩余票数2

剩余票数2

剩余票数2

剩余票数2

剩余票数2

购票成功

购票成功

购票失败

购票失败

购票失败

加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,没错,速度是慢了,但牺牲了速度却保证了数据安全。

虽然可以用文件共享数据实现进程间通信,但问题是:

  1. 效率低(共享数据基于文件,而文件是硬盘上的数据)
  2. 需要自己加锁处理

因此我们最好找寻一种解决方案能够兼顾:

  1. 效率高(多个进程共享一块内存的数据)
  2. 帮我们处理好锁问题。这就是mutiprocessing模块为我们提供的基于消息的IPC通信机制:队列和管道。

队列和管道都是将数据存放于内存中,队列又是基于(管道+锁)实现的,可以让我们从复杂的锁问题中解脱出来,我们应该尽量避免使用共享数据,尽可能使用消息传递和队列,避免处理复杂的同步和锁问题,而且在进程数目增多时,往往可以获得更好的可获展性。

进程同步multiprocess.Lock的更多相关文章

  1. 进程同步(multiprocess.Lock、multiprocess.Semaphore、multiprocess.Event) day38

    进程同步(multiprocess.Lock.multiprocess.Semaphore.multiprocess.Event) 锁 —— multiprocess.Lock 通过刚刚的学习,我们千 ...

  2. Python程序中的进程操作-进程同步(multiprocess.Lock)

    目录 一.多进程抢占输出资源 二.使用锁维护执行顺序 三.多进程同时抢购余票 四.使用锁来保证数据安全 通过刚刚的学习,我们千方百计实现了程序的异步,让多个任务可以同时在几个进程中并发处理,他们之间的 ...

  3. 【python】多进程锁multiprocess.Lock

    [python]多进程锁multiprocess.Lock 2013-09-13 13:48 11613人阅读 评论(2) 收藏 举报  分类: Python(38)  同步的方法基本与多线程相同. ...

  4. 多进程操作-进程锁multiprocess.Lock的使用

    多进程操作-进程锁multiprocess.Lock的使用 ​ 通过之前的Process模块的学习,我们实现了并发编程,虽然更加充分地利用了IO资源,但是也有缺陷:当多个进程共用一份数据资源的时候,就 ...

  5. C#线程/进程同步(lock、Mutex、Semaphore)

    一.lock(实质是Monitor.Enter和Monitor.Exit)(线程同步) 二.Mutex(互斥量)(线程/进程同步) Mutex有个好的特性是,如果程序结束时而互斥锁没通过Release ...

  6. 29、Python程序中的进程操作(multiprocess.process)

    一.multiprocess模块 multiprocess不是一个模块而是python中一个操作.管理进程的包. 子模块分为四个部分: 创建进程部分 进程同步部分 进程池部分 进程之间数据共享 二.m ...

  7. Python之进程

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

  8. 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)

    参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...

  9. Python3-进程

    进程 什么是进程 进程调度 进程的并行与并发 进程的创建与结束 在python程序中的进程操作 守护进程 进程同步(multiprocess.Lock) 进程间通信——队列 生产者消费者模型 进程池和 ...

随机推荐

  1. 用AD 输出BOM时提示failed to open excel template

    解决办法: 去掉这个√!

  2. 说一说我了解的react生命周期函数

    我了解的几个阶段 Mounting 挂载 Updating 更新 Unmounting 卸载 我说几个我常用的钩子函数 1.挂载阶段Mounting 1)constructor():函数构造器 执行次 ...

  3. Linux文件和目录的属性及权限

    Linux文件和目录的属性及权限讲解 文字解释: 第一列:inode索引节点 第二列:文件类型及权限 第三列:硬链接个数 第四列:文件或目录所属的用户(属主) 第五列:文件或目录所属的用户所归属的组( ...

  4. 为什么 execute(`echo 中文`) 输出中文源码?

    为什么 execute(echo 中文) 输出中文源码? import win.ui; /*DSG{{*/ var winform = win.form(text="管道演示";r ...

  5. Thread--CountDownLatch & CyclicBarrier

    参考:http://www.importnew.com/21889.html CountDownLatch countDown() 方法执行完只是计数器减一, 并不会阻塞当前运行线程的的后续代码执行. ...

  6. C语言之结构体概述

    C语言之结构体概述1.结构体类型是一种自定义类型(1)C语言中有2种类型:原生类型和自定义类型.2.结构体使用时先定义结构体类型再用类型定义变量(1)结构体定义时需要先定义结构体类型,再用类型来定义变 ...

  7. 萤火虫系统(firefly) RK3399 python3 安装 tensorflow

    前言: 继续之前在RK3399上安装深度学习的一些环境,主要碰到的坑给大家分享一下,为了让大家少走弯路.这次是安装tensorflow,话不多说,直接开撸. --------------------- ...

  8. PyQt5Day03--程序基本结构之面向对象版本+控件学习

    1.程序基本结构之面向对象版本 (1)开发阶段(自己写好并测试)——设置为模版qto from PyQt5.Qt import * class Window(QWidget): def __init_ ...

  9. python logging的输出

    ---恢复内容开始--- python中logging的使用 什么是日志: 日志是一种可以追踪某些软件运行时所发生事件的方法 软件开发人员可以向他们的代码中调用日志记录相关的方法来表明发生了某些事情 ...

  10. 2020年使用Delphi的25个理由(我觉得四个优点:控件+可视化开发+跨平台+数据库,还有一个编译快,运行快)——人生苦短,我用Delphi!

    25年后从10个使用Delphi的理由到1个至25个使用Delphi 10.3的理由 25年前发布Delphi 1时,我汇总了使用Delphi的十大理由.这是我精通Delphi原始书的序言中的原始列表 ...