python进程间数据传递(python进程和线程之间通信)

本文目录一览:

python3.4.3 多进程之间结果变量的传递问题,程序无任何结果输出

多进程间共享的变量要使用特殊的数据结构,在multiprocessing包里有提供,常用的有Queue, Value, Array等,这里比较适合用Queue

修改后的程序如下,注意Result赋值,和ProcessCheck的参数

另外,Result要排序后输出的话,要用循环从Queue取值构建list再排序,这里省略了

import datetime

import sys

import time

import multiprocessing

PartStart = []       #每个process计算的起点

PartEnd = []         #每个process计算的终点

Result =  multiprocessing.Queue()      #所有结果存储在Result数组中

ProcessCount = 10          #进程数 

EndNum = 9999999           #计算范围,默认100开始,终止数可以任意修改,大于100即可

print(‘Start:%s’ %datetime.datetime.now().strftime(“%Y/%d/%m %H:%M:%S”))

start=time.time()

d=int(((EndNum-99)/ProcessCount)+0.5)

for i in range(ProcessCount):

    PartStart.append(100+i*d)

    PartEnd.append(PartStart[i]+d-1)

PartEnd[ProcessCount-1]=EndNum

#==========================================

#这段代码只是计算每个process的计算起点和终点

def CheckNum(Number):

    tmp=str(Number)

    len_num=len(tmp)

    sum_num = 0

    for i in range(len_num):

        sum_num=sum_num+(int(tmp[i])**len_num)

    if sum_num==int(Number):

        return True

        #print(Number,”是水仙花数”)

    else:

        return False

        #print(Number,”不是水仙花数”)

def ProcessCheck(Start,End, Result):

    for j in range(int(Start),int(End)+1):      

        if CheckNum(j):

            #print(j,”是水仙花数”)

            print(“hello world”)

            Result.put(str(j)+”是水仙花数”)

#============================================

#这段代码用于计算某数值区间内的水仙花数,并存储进result数组中,也是每个process运行的代码

def main():

    threads=[]

    for i in range(ProcessCount):

        p=multiprocessing.Process(target=ProcessCheck, args=(PartStart[i],PartEnd[i], Result))

        threads.append(p)

    for i in range(ProcessCount):

        threads[i].start()

    for i in range(ProcessCount):

        threads[i].join()

    #Result.sort(key=lambda t:t[0])

    for i in range(Result.qsize()):

        print(Result.get())

    #将最后的结果排序输出,但没有任何结果出现

    end = time.time()

    input(‘End:%s’ %datetime.datetime.now().strftime(“%Y/%d/%m %H:%M:%S”)+”\n”+”共耗时:”+str(end-start))

    #这个input没有任何意义,主要是防止程序直接结束退出

if __name__ == ‘__main__’:

    main()

关于Python数据进程间共享

如果两个py运行在两个不同的解释器,应该没有办法直接共享,只能通过转发,如果数据可以序列化,可考虑存储到数据库,其他程序读取

Python多进程运行——Multiprocessing基础教程2

上篇文章简单介绍了multiprocessing模块,本文将要介绍进程之间的数据共享和信息传递的概念。

在多进程处理中,所有新创建的进程都会有这两个特点:独立运行,有自己的内存空间。

我们来举个例子展示一下:

这个程序的输出结果是:

在上面的程序中我们尝试在两个地方打印全局列表result的内容:

我们再用一张图来帮助理解记忆不同进程间的数据关系:

如果程序需要在不同的进程之间共享一些数据的话,该怎么做呢?不用担心,multiprocessing模块提供了Array对象和Value对象,用来在进程之间共享数据。

所谓Array对象和Value对象分别是指从共享内存中分配的ctypes数组和对象。我们直接来看一个例子,展示如何用Array对象和Value对象在进程之间共享数据:

程序输出的结果如下:

成功了!主程序和p1进程输出了同样的结果,说明程序中确实完成了不同进程间的数据共享。那么我们来详细看一下上面的程序做了什么:

在主程序中我们首先创建了一个Array对象:

向这个对象输入的第一个参数是数据类型:i表示整数,d代表浮点数。第二个参数是数组的大小,在这个例子中我们创建了包含4个元素的数组。

类似的,我们创建了一个Value对象:

我们只对Value对象输入了一个参数,那就是数据类型,与上述的方法一致。当然,我们还可以对其指定一个初始值(比如10),就像这样:

随后,我们在创建进程对象时,将刚创建好的两个对象:result和square_sum作为参数输入给进程:

在函数中result元素通过索引进行数组赋值,square_sum通过 value 属性进行赋值。

注意:为了完整打印result数组的结果,需要使用 result[:] 进行打印,而square_sum也需要使用 value 属性进行打印:

每当python程序启动时,同时也会启动一个服务器进程。随后,只要我们需要生成一个新进程,父进程就会连接到服务器并请求它派生一个新进程。这个服务器进程可以保存Python对象,并允许其他进程使用代理来操作它们。

multiprocessing模块提供了能够控制服务器进程的Manager类。所以,Manager类也提供了一种创建可以在不同流程之间共享的数据的方法。

服务器进程管理器比使用共享内存对象更灵活,因为它们可以支持任意对象类型,如列表、字典、队列、值、数组等。此外,单个管理器可以由网络上不同计算机上的进程共享。

但是,服务器进程管理器的速度比使用共享内存要慢。

让我们来看一个例子:

这个程序的输出结果是:

我们来理解一下这个程序做了什么:首先我们创建了一个manager对象

在with语句下的所有行,都是在manager对象的范围内的。接下来我们使用这个manager对象创建了列表(类似的,我们还可以用 manager.dict() 创建字典)。

最后我们创建了进程p1(用于在records列表中插入一条新的record)和p2(将records打印出来),并将records作为参数进行传递。

服务器进程的概念再次用下图总结一下:

为了能使多个流程能够正常工作,常常需要在它们之间进行一些通信,以便能够划分工作并汇总最后的结果。multiprocessing模块支持进程之间的两种通信通道:Queue和Pipe。

使用队列来回处理多进程之间的通信是一种比较简单的方法。任何Python对象都可以使用队列进行传递。我们来看一个例子:

上面这个程序的输出结果是:

我们来看一下上面这个程序到底做了什么。首先我们创建了一个Queue对象:

然后,将这个空的Queue对象输入square_list函数。该函数会将列表中的数平方,再使用 put() 方法放入队列中:

随后使用 get() 方法,将q打印出来,直至q重新称为一个空的Queue对象:

我们还是用一张图来帮助理解记忆:

一个Pipe对象只能有两个端点。因此,当进程只需要双向通信时,它会比Queue对象更好用。

multiprocessing模块提供了 Pipe() 函数,该函数返回由管道连接的一对连接对象。 Pipe() 返回的两个连接对象分别表示管道的两端。每个连接对象都有 send() 和 recv() 方法。

我们来看一个例子:

上面这个程序的输出结果是:

我们还是来看一下这个程序到底做了什么。首先创建了一个Pipe对象:

与上文说的一样,该对象返回了一对管道两端的两个连接对象。然后使用 send() 方法和 recv() 方法进行信息的传递。就这么简单。在上面的程序中,我们从一端向另一端发送一串消息。在另一端,我们收到消息,并在收到END消息时退出。

要注意的是,如果两个进程(或线程)同时尝试从管道的同一端读取或写入管道中的数据,则管道中的数据可能会损坏。不过不同的进程同时使用管道的两端是没有问题的。还要注意,Queue对象在进程之间进行了适当的同步,但代价是增加了计算复杂度。因此,Queue对象对于线程和进程是相对安全的。

最后我们还是用一张图来示意:

Python的multiprocessing模块还剩最后一篇文章:多进程的同步与池化

敬请期待啦!

原创文章,作者:ZM83N,如若转载,请注明出处:https://www.506064.com/n/127884.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
ZM83N的头像ZM83N
上一篇 2024-10-03 23:16
下一篇 2024-10-03 23:16

相关推荐

  • mysql数据库备份策略与恢复,mysql数据库备份策略与恢复策略

    本文目录一览: 1、怎么备份和还原mysql数据库 2、mysql数据库备份和还原 3、如何进行数据库备份和恢复 mysql 怎么备份和还原mysql数据库 备份数据库 使用mys…

    编程 2024-11-04
  • Android开发中必备的生命周期理解

    在Android开发中,生命周期是一个非常重要的概念。每个Android应用程序内的所有组件都会经历生命周期,其定义了组件从创建到销毁的整个过程。当我们了解并正确处理组件的生命周期…

    编程 2024-12-02
  • mysql代码学习,怎么使用mysql写代码

    本文目录一览: 1、mysql学了可以干什么 2、mysql基本语句详细教程 3、MySQL有什么推荐的学习书籍 mysql学了可以干什么 首先技不压身,不管你将来从事什么技术行当…

    编程 2024-10-27
  • Java注释的使用方法

    Java注释是Java语言中的一种特殊语法,可以用于为代码添加解释、描述和说明信息。在编写Java程序时,我们通常需要添加注释来帮助其他开发人员或自己更好地理解代码的含义和功能,从…

    编程 2024-10-03
  • 可重播的大屏图片js广告代码(可重播的大屏图片js广告代码大全)

    1、修改js弹窗广告代码 2、急需要,求一段网页全屏广告的JS代码. 3、求一个网站首页全屏大图广告的代码!可以关闭的 4、JS广告代码 修改TOP的数值。 document.wr…

    编程 2024-10-03
  • java注册,Java注册表

    本文目录一览: 1、性能测试中如何使用java批量注册登录账户 2、java代码写注册,注册完成后,怎么写提示注册成功 3、Java程序怎么注册成windows服务? 4、java…

    编程 2024-11-10
  • Linux环境变量设置方法

    环境变量是操作系统中一个非常重要的概念,它可以定义全局的配置,而且可以被应用程序访问。在Linux系统中,环境变量也是非常重要的东西,因为它可以影响着系统和应用的行为。本文将从多个…

    编程 2024-12-10
  • java绘图,java绘图jar包

    本文目录一览: 1、java绘图类的graphics的drawLine(x1,y2,x2,y2)四个参数分别指什么 2、怎么用JAVA画半个圆或者是半圆弧? 3、在Java中如何用…

    编程 2024-10-04
  • php的完整(php的完整代码块是)

    本文目录一览: 1、一个完整的PHP类包含的七种语法说明 2、开发PHP完整项目需要那些工具 3、php完整的代码块是什么意思 一个完整的PHP类包含的七种语法说明 这篇文章主要介…

    编程 2024-10-03
  • 使用C++创建二维数组

    一、定义和初始化二维数组 C++中创建一个二维数组需要指定行和列,可以用下面的语法来定义一个二维数组: int arr[row][col]; 其中,row和col都为整数类型的变量…

    编程 2024-10-04

发表回复

登录后才能评论