3.3.3 进程数据共享

进程间数据交互

我们知道,两个独立进程所使用的内存空间也是独立的,不可交互的。

但现实中就有那么些情况需要两个进程可以互相通信,怎么办?

我们需要一个中继、翻译、中间人,不管你叫他什么,只要知道他是用来转发数据的就行了。

Python中的这个中间人就叫queue,不是线程queue,是进程queue。使用方法和线程queue差不多。

示例如下:

from multiprocessing import Process, Queue

def f(q):
    q.put([42, None, ‘Hello‘])    #3 子进程给中间人传递消息

if __name__ == ‘__main__‘:
    q = Queue()    #1 中间人
    p = Process(target=f, args=(q, ))    #2 传递中间人给子进程
    p.start()
    print(q.get())    #4 父进程得到消息

结果

[42, None, ‘Hello‘]

Pipe()

The Pipe() function returns a pair of connection objects connected by a pipe which by default is duplex (two-way). For example:

from multiprocessing import Process, Pipe

def f(conn):
    conn.send([42, None, ‘hello‘])    #3子进程执行的f()函数发送一条消息
    conn.close()

if __name__ == ‘__main__‘:
    parent_conn, child_conn = Pipe()    #1管道的两端
    p = Process(target=f, args=(child_conn,))
    p.start()    #2启动一个子进程,子进程执行f()函数
    print(parent_conn.recv())    #4输出父进程通过管道接收到的消息

结果

[42, None, ‘hello‘]

The two connection objects returned by Pipe() represent the two ends of the pipe. Each connection object has send

由Pipe()函数返回的两个连接对象表示管道的两端。每个链接对象都由send()

() and recv() methods (among others). Note that data in a pipe may become corrupted if two processes (or threads) try

和recv()方法。注意如果两个进程(或线程)尝试同时从管道的同一头读取或者写入时管道中的数据可能出错。

to read from or write to the same end of the pipe at the same time. Of course there is no risk of corruption from processes

当然,多进程同时使用管道不同的终端,是没有出错风险的。

using different ends of the pipe at the same time.

以上2个方法,多进程的queue和pipe都只能实现进程间数据的传递,但还没有涉及进程间的数据共享

Managers

A manager object returned by Manager() controls a server process which holds Python objects and allows other processes

Manager()返回一个管理器对象,管理器对象控制一个服务进程,该进程持有Python对象并允许其他进程使用代理操作这些Python对象

to manipulate them using proxies.

A manager returned by Manager() will support

由Manager()返回的管理器支持以下类型

types list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value

and Array. For example

示例

from multiprocessing import Manager, Process
import os

def f(d, l):
    d[1] = ‘1‘
    d[‘2‘] = 2
    d[0.25] = None
    l.append(os.getpid())    #4每次进程循环,添加当前进程ID
    print(l)

if __name__ == ‘__main__‘:
    m = Manager()    #1管理器对象
    d = m.dict()    #2管理器对象所持有的Python对象,字典
    l = m.list(range(5))    #同上,列表,这里预存了5个值
    p_list = []
    for i in range(10):
        p = Process(target=f, args=(d, l))    #3子进程执行f()函数,传递上面2个Python对象
        p.start()
        p_list.append(p)
    for res in p_list:
        res.join()
    print(‘dict: ‘, d)    #5输出结果
    print(‘list: ‘, l)

结果

[0, 1, 2, 3, 4, 7836]
[0, 1, 2, 3, 4, 7836, 9132]
[0, 1, 2, 3, 4, 7836, 9132, 10504]
[0, 1, 2, 3, 4, 7836, 9132, 10504, 11156]
[0, 1, 2, 3, 4, 7836, 9132, 10504, 11156, 10712]
[0, 1, 2, 3, 4, 7836, 9132, 10504, 11156, 10712, 7188]
[0, 1, 2, 3, 4, 7836, 9132, 10504, 11156, 10712, 7188, 15244]
[0, 1, 2, 3, 4, 7836, 9132, 10504, 11156, 10712, 7188, 15244, 6944]
[0, 1, 2, 3, 4, 7836, 9132, 10504, 11156, 10712, 7188, 15244, 6944, 13088]
[0, 1, 2, 3, 4, 7836, 9132, 10504, 11156, 10712, 7188, 15244, 6944, 13088, 12932]
dict:  {1: ‘1‘, ‘2‘: 2, 0.25: None}
list:  [0, 1, 2, 3, 4, 7836, 9132, 10504, 11156, 10712, 7188, 15244, 6944, 13088, 12932]

可以看到,父进程子进程对同一份数据进行了修改,实现了数据的共享。

原文地址:https://www.cnblogs.com/infinitecodes/p/12127376.html

时间: 2024-10-31 04:11:05

3.3.3 进程数据共享的相关文章

进程数据共享

进程各自持有一份数据,默认无法共享数据 #!/usr/bin/env python #coding:utf-8 from multiprocessing import Process from multiprocessing import Manager import time li = [] def foo(i): li.append(i) print 'say hi',li for i in range(10): p = Process(target=foo,args=(i,)) p.sta

进程数据共享-进程池

数据共享 Manager  内部管理了很多数据类型,并不是所有的数据类型都是用来做数据分享,只是顺便包含了能够处理数据共享问题的数据类型 list dict 列表/字典  自带的方法基本都是数据安全的,但是对其中的元素进行+= -= *=  /=   都是数据不安全的 from multiprocessing import Manager,Process,Lock def func(dic,lock): with lock: dic['count'] -= 1 if __name__ == '_

第36篇 多进程的数据共享,进程池的回调函数,线程 什么是GIL锁,Threading模块记

内容概览: 进程 数据共享 进程池--回调函数 线程 线程的基础理论 什么是线程? 线程与进程的关系 GIL锁 线程的开启: Threading模块1,用多进程开启socket创建聊天 server端写了input函数会报错?因为服务器是高速运行的,自动化的为来访问的客户端提供服务, 不可能停下来等待管理员的输入,然后发送给客户.这就失去了自动化的意义. 2,进程池Pool()方法创建的进程,map()方法是否有返回值? p.map()得到的是迭代对象 import time from mult

Python之路【第七篇】:线程、进程和协程

Python之路[第七篇]:线程.进程和协程 Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/usr/bin/env python # -*- coding:utf-8 -*- import threading import time   def show(arg):     time.sleep(1)     print 'thread'+str(arg)   for i in

Python:简述 线程、进程和协程

Python线程 定义:Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. #!/usr/bin/env python # -*- coding:utf-8 -*- import threading import time def show(arg): time.sleep(1) print 'thread'+str(arg) for i in range(10): t = threading.Thread(target=show, args=(i,)) t.start(

进程、线程

进程与线程 进程与线程的关系 进程: 优点:同时利用多个cpu,能够同时进行多个操作 缺点:耗费资源(重新开辟内存空间) 线程: 优点:共享内存,IO操作的时候,创造并发操作 缺点:抢占资源 进程不是越多越好,cpu个数 = 进程个数 线程也不是越多越好,具体案例具体分析,请求上下文切换耗时 计算机中执行任务的最小单元:线程 IO操作利用cpu GIL 全局解释锁 IO密集型(不用cpu): 多线程 计算密集型(用cpu): 多进程 进程和线程的目的:提高执行效率1,截止目前写的程序:单进程单线

线程、进程和协程

Treading用于提供线程相关的操作,线程是应用程序中工作的最小单元 #!/usr/bin/env python # coding:utf-8 import threading import time def show(arg): time.sleep(1) print 'thread'+str(arg) for i in range(10): t = threading.Thread(target=show,args=(i,)) t.start() print 'main thread st

Python之线程与进程

1.程序 程序指的是指令的集合:程序不能单独的运行,必须将程序装载在内存中,系统给它分配资源才可以运行. 程序是进程动态运行的静态描述文本 2.进程 进程指的是程序在数据集中一次动态运行的过程: 3.线程 线程进程的最小执行单位,真正在CPU运行的是线程 4.进程与线程的关系 一个线程只能在一个进程里面,一个进程可以包含多个线程: 进程是资源管理单位(容器)  线程是最小执行单位 5.并行与并发 并行:指的是同时处理多个任务(多个线程被不同的CPU执行) 并发:指的是交替处理多个任务(多个线程被

【Python学习之路】——Day10(线程、进程)

Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. #!/usr/bin/env python # -*- coding:utf-8 -*- import threading import time def show(arg): time.sleep(1) print 'thread'+str(arg) for i in range(10): t = threading.Thread(target=show, args=(i,)) t.start() p