1. 互斥锁

​ 当多个进程抢占同一数据时,将数据加锁,使进程按串行的方式去获取数据,先到先得,保证了公平、数据的安全。

​ lock.acquire() # 加锁

​ lock.release() # 释放

​ 死锁:连续lock.acquice() 多次,会阻塞进程。

# 模拟三个用户使用同一个打印机打印。
from multiprocessing import Process
from multiprocessing import Lock # 导入互斥锁
import os
import time
import random
import sys def task1(lock): lock.acquire() # 加锁
print(f'task1-{os.getpid()}开始打印!')
time.sleep(random.randint(1,3))
print(f'task1-{os.getpid()}打印结束!')
lock.release() # 解锁释放 def task2(lock): lock.acquire()
print(f'task2-{os.getpid()}开始打印!')
time.sleep(random.randint(1,3))
print(f'task2-{os.getpid()}打印结束!')
lock.release() def task3(lock): lock.acquire()
print(f'task3-{os.getpid()}开始打印!')
time.sleep(random.randint(1,3))
print(f'task3-{os.getpid()}打印结束!')
lock.release() if __name__ == '__main__':
mutex = Lock()
for i in range(1,4):
p = Process(target=getattr(sys.modules[__name__], f'task{i}'), args=(mutex,))
p.start()
# 优化,多个用户打印

from multiprocessing import Process
from multiprocessing import Lock
import os
import time
import random def task(lock, i): lock.acquire()
print(f'用户{i}:{os.getpid()}开始打印!')
time.sleep(random.randint(1,3))
print(f'用户{i}:{os.getpid()}打印结束!')
lock.release() if __name__ == '__main__':
mutex = Lock()
for i in range(1,5):
p = Process(target=task, args=(mutex, i))
p.start()

Lock与join对比:

​ 相同点:都可以把并发变成串行,保证了顺序。

​ 不同点:join是人为设定的顺序;Lock是让其竞争顺序,保证公平性。

2. 进程之间的通信

​ 进程在内存级别是隔离的,但是文件在磁盘上是共享的。

2.1 基于文件的通信

当多个进程共同争抢一个数据、资源时,如果要保证顺序、数据的安全,必须要串行。

缺点:效率低;需人为加锁容易出现死锁。


# 模拟抢票系统,5个用户抢1张票。(查票时是并发的,但购票时是串行的)
# 文件ticket_json 中写入{"count":1} from multiprocessing import Process
from multiprocessing import Lock
import time
import os
import random
import json def search(): # 查看余票
time.sleep(random.random())
with open('ticket_json','r', encoding='utf-8') as f1:
dic = json.load(f1)
print(f'{os.getpid()}查看余票:{dic["count"]}') def paid(): # 购票
with open('ticket_json','r', encoding='utf-8') as f1:
dic = json.load(f1)
if dic["count"] > 0:
dic["count"] -= 1
time.sleep(random.randint(1,2))
with open('ticket_json','w', encoding='utf-8') as f2:
json.dump(dic,f2)
print(f'{os.getpid()}购票成功!')
else:
print(f"{os.getpid()}:已没票!") def task(lock): # 子进程
search()
lock.acquire() #购票加锁
paid()
lock.release() if __name__ == '__main__':
mutex = Lock()
for i in range(6): # 5个用户抢1张票
p = Process(target=task, args=(mutex,))
p.start()

2.2 基于队列的通信

队列:存在于内存,可以理解是一个容器。可以承载一些数据。

特性:先进先出,FIFO。

from multiprocessing import Queue

def func():
print('is func')
class Q:
pass
obj = Q() q = Queue(4) # 最大承载4个数据
q.put(1) #添加数据到队列中
q.put([2])
q.put(func)
q.put(obj)
#q.put(111) # 超出会阻塞 for i in range(5):
print(q.get()) # 依次取出数据,当没数据时,再get会阻塞
# 队列Queue中的一些方法参数
q = Queue(n) # maxsize = n 最大承载n个数据
q.qsize() # 获取队列的元素个数
q.empty() # 判断队列是否为空
q.full() # 判断队列是否满
put(self, obj, block=True, timeout=None)
get(self, block=True, timeout=None)
# 队列满时,再put会阻塞,直到某个进程get()数据时,会添加进去。
# 队列没数据时,再get会阻塞,直到某个进程put()数据时,会取出。 block = True : 默认阻塞。当写block=False时,只有遇到阻塞就会报错。
q.put(11,block=False) # 当队列满时,会报错
q.get(block=False) # 当队列满无数据时时,会报错 timeout = 3 # 阻塞3秒,3秒后还是阻塞状态就会报错。
# 用队列购票

from multiprocessing import Process
from multiprocessing import Queue
import os
import time
import random def search(q): # 查看余票
print(f"用户-{os.getpid()}查看余票:{q.qsize()}票") def paid(q): # 购票
if q.qsize() > 0:
q.get()
print(f"用户-{os.getpid()},购票成功")
else:
print(f"用户-{os.getpid()},购票失败") def task(q):
search(q)
time.sleep(random.random()) # 网络延迟
paid(q) if __name__ == '__main__':
q = Queue(10)
for i in range(3): # 3张票
q.put(1)
for i in range(5): # 5个用户
p = Process(target=task, args=(q,))
p.start()

python 34 多进程(二)的更多相关文章

  1. Python编程-多进程二

    7.进程间通信(IPC)方式二:管道 (1)创建管道的类: Pipe([duplex]):在进程之间创建一条管道,并返回元组(conn1,conn2),其中conn1,conn2表示管道两端的连接对象 ...

  2. Python第十二章-多进程和多线程01-多进程

    多进程和多线程 一.进程 1.1 进程的引入 现实生活中,有很多的场景中的事情是同时进行的,比如开车的时候 手和脚共同来驾驶汽车,再比如唱歌跳舞也是同时进行的:试想,如果把唱歌和跳舞这2件事情分开依次 ...

  3. python下实现二叉堆以及堆排序

    python下实现二叉堆以及堆排序 堆是一种特殊的树形结构, 堆中的数据存储满足一定的堆序.堆排序是一种选择排序, 其算法复杂度, 时间复杂度相对于其他的排序算法都有很大的优势. 堆分为大头堆和小头堆 ...

  4. 『Python』多进程处理

    尝试学习python的多进程模组,对比多线程,大概的区别在: 1.多进程的处理速度更快 2.多进程的各个子进程之间交换数据很不方便 多进程调用方式 进程基本使用multicore() 进程池优化进程的 ...

  5. python 使用多进程实现并发编程/使用queue进行进程间数据交换

    import time import os import multiprocessing from multiprocessing import Queue, pool ""&qu ...

  6. Python多线程多进程

    一.线程&进程 对于操作系统来说,一个任务就是一个进程(Process),比如打开一个浏览器就是启动一个浏览器进程,打开一个记事本就启动了一个记事本进程,打开两个记事本就启动了两个记事本进程, ...

  7. Python爬虫实战二之爬取百度贴吧帖子

    大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 前言 亲爱的们,教程比较旧了,百度贴吧页面可能改版,可能代码不 ...

  8. python排序之二冒泡排序法

    python排序之二冒泡排序法 如果你理解之前的插入排序法那冒泡排序法就很容易理解,冒泡排序是两个两个以向后位移的方式比较大小在互换的过程好了不多了先上代码吧如下: 首先还是一个无序列表lis,老规矩 ...

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

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

随机推荐

  1. 多线程与高并发(五)final关键字

    final可以修饰变量,方法和类,也就是final使用范围基本涵盖了java每个地方,我们先依次学习final的基础用法,然后再研究final关键字在多线程中的语义. 一.变量 变量,可以分为成员变量 ...

  2. spark 源码分析之十八 -- Spark存储体系剖析

    本篇文章主要剖析BlockManager相关的类以及总结Spark底层存储体系. 总述 先看 BlockManager相关类之间的关系如下: 我们从NettyRpcEnv 开始,做一下简单说明. Ne ...

  3. 【Java中级】(三)IO

    1. 流分为字节流和字符流 2. 字节流下面常用的又有数据流和对象流 3. 字符流下面常用的又有缓存流 文件对象 文件和文件夹都用File表示 //file path : 文件的绝对路径或相对路径Fi ...

  4. 《VR入门系列教程》之18---Oculus代码剖析

    代码剖析 原文作者:Tony Parisi     那么,Unity究竟是如何支持Oculus VR运行的?首先,我们来看看Unity场景是如何构建的.在Unity集成开发包中有一个相机预设体,这个预 ...

  5. Linux小火车和流星雨

    一.流星雨 [root@localhost ~]# wget https://jaist.dl.sourceforge.net/project/cmatrix/cmatrix/1.2a/cmatrix ...

  6. 深入理解Java中的AQS

    AQS概述 ​ AbstractQueuedSynchronizer抽象队列同步器简称AQS,它是实现同步器的基础组件,juc下面Lock的实现以及一些并发工具类就是通过AQS来实现的,这里我们通过A ...

  7. Task CancellationTokenSource和Task.WhenAll的应用

    Task是.net4.0推出的异步编程类,与ThreadPool.QueneUserWorkItem方法类似的是,Task也是使用线程池来工作的.但Task比起这个QueneUserWorkItem的 ...

  8. 重入锁的学习 (ReentrantLock)

    重入锁  :(ReentrantLock) 上锁 用reentrantLock.lock 方法 解锁 用reentrantLock.unlock 方法 上锁和解锁 必须配对 可以多重上锁 Reentr ...

  9. PYNQ上手笔记 | ① 启动Pynq

    现在人工智能非常火爆,一般的教程都是为博硕生准备的,太难看懂了,分享一个非常适合小白入门的教程,不仅通俗易懂而且还很风趣幽默,点☞这里​​​​​​​☜进入传送门~ = = = = 我是华丽的分割线 = ...

  10. 自定义 Button 选择器

    极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以 ...