37. Python 多进程锁 多进程共享内存

Lock组件

当我们用多进程来读写文件的时候,如果一个进程是写文件,一个进程是读文件,

如果两个文件同时进行,肯定是不行的,必须是文件写结束后,才可以进行读操作。

或者是多个进程在共享一些资源的时候,同时只能有一个进程进行访问,那就需要锁机制进行控制。

需求:

一个进程写入一个文件,一个进程追加文件,一个进程读文件,同时启动起来

我们可以通过进程的join()方法来实现,这是一种方法,本节用Lock(进程锁)来实现。

函数说明:

# lock = multiprocessing.Lock()

# lock.acquire() ? ? ? ? ? ? ? ?#获得锁

# lock.release() ? ? ? ? ? ? ? ?#释放锁

先写不加锁的程序:

#不加锁

# number ?+1

# number ?+3

import?multiprocessing
import?time
def?add(number,value,lock):
????print?("init?add{0}?number?=?{1}".format(value,?number))
????for?i?in?xrange(1,?6):
????????number?+=?value
????????time.sleep(1)
????????print?("add{0}?number?=?{1}".format(value,?number))
????????
if?__name__?==?"__main__":
????lock?=?multiprocessing.Lock()
????number?=?0
????p1?=?multiprocessing.Process(target=add,args=(number,?1,?lock))
????p2?=?multiprocessing.Process(target=add,args=(number,?3,?lock))
????p1.start()
????p2.start()
????print?("main?end")

结果:

main?end
init?add1?number?=?0
init?add3?number?=?0
add1?number?=?1
add3?number?=?3
add1?number?=?2
add3?number?=?6
add1?number?=?3
add3?number?=?9
add1?number?=?4
add3?number?=?12
add1?number?=?5
add3?number?=?15

再写加锁的程序:

import?multiprocessing
import?time
def?add(number,value,lock):
????with?lock:
????print?("init?add{0}?number?=?{1}".format(value,?number))
????for?i?in?xrange(1,?6):
????????number?+=?value
????????time.sleep(1)
????????print?("add{0}?number?=?{1}".format(value,?number))
????????
if?__name__?==?"__main__":
????lock?=?multiprocessing.Lock()
????number?=?0
????p1?=?multiprocessing.Process(target=add,args=(number,?1,?lock))
????p2?=?multiprocessing.Process(target=add,args=(number,?3,?lock))
????p1.start()
????p2.start()
????print?("main?end")

结果:

main?end
init?add1?number?=?0			#add1优先抢到锁,优先执行
add1?number?=?1
add1?number?=?2
add1?number?=?3
add1?number?=?4
add1?number?=?5
init?add3?number?=?0			#add3被阻塞,等待add1执行完成,释放锁后执行add3
add3?number?=?3
add3?number?=?6
add3?number?=?9
add3?number?=?12
add3?number?=?15

使用 lock.acquire() 和 lock.release()

import?multiprocessing
import?time
def?add(number,value,lock):
????lock.acquire()
????try:
????????print?("init?add{0}?number?=?{1}".format(value,?number))
????????for?i?in?xrange(1,?6):
????????????number?+=?value
????????????time.sleep(1)
????????????print?("add{0}?number?=?{1}".format(value,?number))
????except?Exception?as?e:
????????raise?e
????finally:
????????lock.release()

if?__name__?==?"__main__":
????lock?=?multiprocessing.Lock()
????number?=?0
????p1?=?multiprocessing.Process(target=add,args=(number,?1,?lock))
????p2?=?multiprocessing.Process(target=add,args=(number,?3,?lock))
????p1.start()
????p2.start()
????print?("main?end")

结果:

main?end
init?add1?number?=?0
add1?number?=?1
add1?number?=?2
add1?number?=?3
add1?number?=?4
add1?number?=?5
init?add3?number?=?0
add3?number?=?3
add3?number?=?6
add3?number?=?9
add3?number?=?12
add3?number?=?15

共享内存

python的multiprocessing模块也给我们提供了共享内存的操作

一般的变量在进程之间是没法进行通讯的,multiprocessing 给我们提供了 Value 和 Array 模块,他们可以在不通的进程中共同使用

例子:不加锁,让number加完1后再继续加3,再继续加一,再继续加3...

import?multiprocessing
import?time
def?add(number,add_value):
????try:
????????print?("init?add{0}?number?=?{1}".format(add_value,?number.value))
????????for?i?in?xrange(1,?6):
????????????number.value?+=?add_value
????????????print?("***************add{0}?has?added***********".format(add_value))
????????????time.sleep(1)
????????????print?("add{0}?number?=?{1}".format(add_value,?number.value))
????except?Exception?as?e:
????????raise?e
????????
if?__name__?==?"__main__":
????number?=?multiprocessing.Value(‘i‘,?0)
????p1?=?multiprocessing.Process(target=add,args=(number,?1))
????p2?=?multiprocessing.Process(target=add,args=(number,?3))
????p1.start()
????p2.start()
????print?("main?end")

打印结果:

main?end
init?add1?number?=?0
***************add1?has?added***********
init?add3?number?=?1
***************add3?has?added***********
add1?number?=?4
***************add1?has?added***********
add3?number?=?5
***************add3?has?added***********
add1?number?=?8
***************add1?has?added***********
add3?number?=?9
***************add3?has?added***********
add1?number?=?12
***************add1?has?added***********
add3?number?=?13
***************add3?has?added***********
add1?number?=?16
***************add1?has?added***********
add3?number?=?17
***************add3?has?added***********
add1?number?=?20
add3?number?=?20

再给加上锁:

加1的进程加完后,再执行加上3的进程

import?multiprocessing
import?time
def?add(number,add_value,lock):
????lock.acquire()
????try:
????????print?("init?add{0}?number?=?{1}".format(add_value,?number.value))
????????for?i?in?xrange(1,?6):
????????????number.value?+=?add_value
????????????print?("***************add{0}?has?added***********".format(add_value))
????????????time.sleep(1)
????????????print?("add{0}?number?=?{1}".format(add_value,?number.value))
????except?Exception?as?e:
????????raise?e
????finally:
????????lock.release()
????????
if?__name__?==?"__main__":
????lock?=?multiprocessing.Lock()
????number?=?multiprocessing.Value(‘i‘,?0)
????p1?=?multiprocessing.Process(target=add,args=(number,?1,?lock))
????p2?=?multiprocessing.Process(target=add,args=(number,?3,?lock))
????p1.start()
????p2.start()
????print?("main?end")

执行结果(对比上面):

main?end
init?add1?number?=?0
***************add1?has?added***********
add1?number?=?1
***************add1?has?added***********
add1?number?=?2
***************add1?has?added***********
add1?number?=?3
***************add1?has?added***********
add1?number?=?4
***************add1?has?added***********
add1?number?=?5
init?add3?number?=?5
***************add3?has?added***********
add3?number?=?8
***************add3?has?added***********
add3?number?=?11
***************add3?has?added***********
add3?number?=?14
***************add3?has?added***********
add3?number?=?17
***************add3?has?added***********
add3?number?=?20

多进程共享内存实现:

import?multiprocessing
import?time
def?add(number,add_value,lock):
????lock.acquire()
????try:
????????print?("init?add{0}?number?=?{1}".format(add_value,?number.value))
????????for?i?in?xrange(1,?6):
????????????number.value?+=?add_value
????????????print?("***************add{0}?has?added***********".format(add_value))
????????????time.sleep(1)
????????????print?("add{0}?number?=?{1}".format(add_value,?number.value))
????????except?Exception?as?e:
????????????raise?e
????????finally:
????????????lock.release()

def?change(arr):
????for?i?in?range(len(arr)):
????????arr[i]?=?-arr[i]
????????
if?__name__?==?"__main__":
????lock?=?multiprocessing.Lock()
????number?=?multiprocessing.Value(‘i‘,?0)
????arr?=?multiprocessing.Array(‘i‘,?range(10))
????print?(arr[:])
????p1?=?multiprocessing.Process(target=add,args=(number,?1,?lock))
????p2?=?multiprocessing.Process(target=add,args=(number,?3,?lock))
????p3?=?multiprocessing.Process(target=change,args=(arr,))
????p1.start()
????p2.start()
????p3.start()
????p3.join()
????print?(arr[:])
????print?("main?end")

结果:

[0,?1,?2,?3,?4,?5,?6,?7,?8,?9]
init?add3?number?=?0
***************add3?has?added***********
[0,?-1,?-2,?-3,?-4,?-5,?-6,?-7,?-8,?-9]
main?end
add3?number?=?3
***************add3?has?added***********
add3?number?=?6
***************add3?has?added***********
add3?number?=?9
***************add3?has?added***********
add3?number?=?12
***************add3?has?added***********
add3?number?=?15
init?add1?number?=?15
***************add1?has?added***********
add1?number?=?16
***************add1?has?added***********
add1?number?=?17
***************add1?has?added***********
add1?number?=?18
***************add1?has?added***********
add1?number?=?19
***************add1?has?added***********
add1?number?=?20
时间: 2024-11-06 07:56:14

37. Python 多进程锁 多进程共享内存的相关文章

C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转

原文:C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped 转 节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing). 内存映射文件对于托管世界的开发人员来说似乎很陌生,但它确实已经是很远古的技术了,而且在操作系统中地位相当.实际上,任何想要共享数据的通信模型都会在幕后使用它. 内存映射文件究竟是个什么?内存映射文件允许你保留一块地址空间,然后将该物理存储映射到这块内存空间中进行操作.物理存储是文件管理,而内存

C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped

节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing). 内存映射文件对于托管世界的开发人员来说似乎很陌生,但它确实已经是很远古的技术了,而且在操作系统中地位相当.实际上,任何想要共享数据的通信模型都会在幕后使用它. 内存映射文件究竟是个什么?内存映射文件允许你保留一块地址空间,然后将该物理存储映射到这块内存空间中进行操作.物理存储是文件管理,而内存映射文件是操作系统级内存管理. 优势:     1.访问磁盘文件上的数据不需执行I/O操作和缓存

linux ftok()函数 --多进程IPC之共享内存

系统建立IPC通讯(如消息队列.共享内存时)必须指定一个ID值.通常情况下,该id值通过ftok函数得到.ftok原型如下:key_t ftok( char * fname, int id ) fname就时你指定的文件名(该文件必须是存在而且可以访问的),id是子序号,虽然为int,但是只有8个比特被使用(0-255). 当成功执行的时候,一个key_t值将会被返回,否则 -1 被返回. 在一般的UNIX实现中,是将文件的索引节点号取出,前面加上子序号得到key_t的返回值.如指定文件的索引节

35 守护进程 互斥锁 IPC 共享内存 的方式 生产者消费者模型

守护进程 进程:一个正在运行的程序. 主进程创建守护进程: 1.守护进程会在主进程代码执行结束后就终止, 2.守护进程内无法再开启子进程,否则抛出异常. 注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止. 例子:from multiprocessing import Processimport time def task(): print('老了....') time.sleep(2) print('睡了一会..') if __name__ == '__main__': prin

Linux下用信号量实现对共享内存的访问保护

转自:http://www.cppblog.com/zjl-1026-2001/archive/2010/03/03/108768.html 最近一直在研究多进程间通过共享内存来实现通信的事情,以便高效率地实现对同一数据的访问.本文中对共享内存的实现采用了系统V的机制,我们的重点在于通过信号量来完成对不同进程间共享内存资源的一致性访问,共享内存的具体方法请参见相关资料,这里不再赘述. 首先我们先实现最简单的共享内存,一个进程对其更新,另一个进程从中读出数据.同时,通过信号量的PV操作来达到对共享

qt 共享内存(QSharedMemory)

——————————————————写入部分—————————————————— (本次程序基于控制台程序) 首先 使用共享内存得召唤一下: #include <QSharedMemory> 然后 声明QSharedMemory类.并且命名为smem QSharedMemory smem; 由于共享内存没有访问密钥,则不能找到共享的内存.我们给他设置一下访问密钥 QString key,sharedstring; 设置访问密钥 qDebug() << "Please in

python学习笔记——多进程中共享内存Value &amp; Array

1 共享内存 基本特点: (1)共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝. (2)为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程将其映射到自己的私有地址空间.进程就可以直接读写这一块内存而不需要进行数据的拷贝,从而大大提高效率.(文件映射) (3)由于多个进程共享一段内存,因此也需要依靠某种同步机制. 优缺点: 优点:快速在进程间传递数据 缺点: 数据安全上存在风险,内存中的内容会被其他进程覆盖或 者篡改 注: 经常和同步互斥

python多进程共享内存

from multiprocessing import Process,Manager,Lock import os import time def run_proc(dict,slip,lock): tmp=dict[slip].copy() for k in dict[slip]: tmp[k]=k+tmp[k] print('Run child process{ch}... '.format(ch=os.getpid())) with lock: dict[slip]=tmp if __n

共享内存,多进程间共享结构体

共享内存 中 存结构体,多线程多进程间实现共享. #define FILE_MSG_KEY 0xc54be5 ///< File message key. #define PROC_MEM_SIZE 4096*3 #define MAX_SHARE_PROC 9 #define IPC_CREAT 00001000 /* create if key is nonexistent */ static int mFileId,qFileId; static void *pShareMem; int