无法从 Python 进程中返回附加值

发布于 2024-10-06 09:21:21 字数 904 浏览 3 评论 0原文

我在 Ubuntu 8.10 上运行 Python 2.6.5。

对于我正在从事的项目,我需要同时运行多个进程并将每个进程的输出保存到各自的列表中。由于我无法直接从进程返回输出值,因此我将输出列表作为参数传递给我的目标函数,并将输出附加到该列表。问题是,当我在运行进程后尝试访问该列表时,该列表仍然是空的。下面是我遇到的问题的简化版本以及错误消息。

代码:

from multiprocessing import Process
import sys, math, os,commands

outputs = []

def calculate(a,b,outputs):
    c = a*b
    outputs.append(c)
    #return c

outputs1 = []

p1 = Process(target = calculate, args = (2,3,outputs1))

p1.start()
p1.join()

print 'len(outputs1) = ' + str(len(outputs1))

print 'outputs1 = ' + str(outputs1[0])

错误:

len(outputs1) = 0
Traceback (most recent call last):
  File "append_test.py", line 23, in <module>
    print 'outputs1 = ' + str(outputs1[0])
IndexError: list index out of range

我试图使每个进程完全独立于其他进程,以免损坏数据。我已经研究过尝试使用多处理中的数组模块,但附加似乎特定于列表。当我使用线程而不是进程运行完全相同的代码时,我毫无问题地获得了所需的输出,这使我相信这是内存共享的问题。

I am running Python 2.6.5 on Ubuntu 8.10.

For a project I am working on, I need to run several processes concurrently and save each of their outputs into their own respective lists. Since I can't return the output value directly from the process, I am passing the output list as an argument to my target function and appending the output to that list. The problem is that when I try to access that list after running the process, the list is still empty. A simplified version of the problem I'm having is below along with the error message.

Code:

from multiprocessing import Process
import sys, math, os,commands

outputs = []

def calculate(a,b,outputs):
    c = a*b
    outputs.append(c)
    #return c

outputs1 = []

p1 = Process(target = calculate, args = (2,3,outputs1))

p1.start()
p1.join()

print 'len(outputs1) = ' + str(len(outputs1))

print 'outputs1 = ' + str(outputs1[0])

Error:

len(outputs1) = 0
Traceback (most recent call last):
  File "append_test.py", line 23, in <module>
    print 'outputs1 = ' + str(outputs1[0])
IndexError: list index out of range

I am trying to keep each process completely independent of the others for fear of corrupting data. I've looked into trying to use the Array module from multiprocessing, but it appears that append is specific to lists. When I run the exact same code with Thread instead of Process, I get the desired output with no problem, which leads me to believe this is an issue of memory sharing.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

野味少女 2024-10-13 09:21:21

当您使用单独的进程时,每个进程都会获得内存中所有内容的自己的副本。这就是为什么父进程在其输出中看不到任何内容:每个子进程都附加到其自己的输出副本。

您需要使用某种形式的进程间通信。 Python 的 multiprocessing 库为此提供了两个功能:管道和队列

例如,使用队列

>>> from multiprocessing import Process, Queue
>>> def f(q): q.put("hello from the child process")
... 
>>> q = Queue()
>>> p = Process(target=f, args=(q,))
>>> p.start()
>>> p.join()
>>> q.get()
'hello from the child process'

When you use separate processes, each process gets its own copy of everything in memory. That's why the parent process never sees anything in its outputs: each child process is appending to its own copy of outputs.

You need to use some form of interprocess communication. Python's multiprocessing library supplies two features for this: pipes and queues.

For example, using a Queue:

>>> from multiprocessing import Process, Queue
>>> def f(q): q.put("hello from the child process")
... 
>>> q = Queue()
>>> p = Process(target=f, args=(q,))
>>> p.start()
>>> p.join()
>>> q.get()
'hello from the child process'
以可爱出名 2024-10-13 09:21:21

标题为在进程之间交换对象multiprocessing模块的在线文档中,它[仅]“支持进程之间的两种类型的通信通道”,并继续提到队列管道。值得注意的是,它没有提到列出outputs1这样的对象。这是有道理的,因为这两个进程不共享内存。

我不确定,但我也怀疑您可能需要将创建进程并启动它的代码部分等放在 if __name__ == '__main__': 子句中以防止子流程来自创建子子流程。

总之,我认为您将不得不重新设计一些东西,以使用这两者之一进行进程间通信——对我来说,队列似乎是合理的选择。

The section titled Exchanging objects between processes in the in the online documentation of themultiprocessingmodule says that it [only] "supports two types of communication channel between processes" and goes on to mention Queues and Pipes. Notably it does not mentionlistobjects likeoutputs1. This makes sense because the two processes don't share memory AFAIK.

I'm not sure, but I also suspect you might need to put the section of your code that creates the process and starts it, etc inside of anif __name__ == '__main__':clause to prevent the subprocess from creating a sub-subprocess.

In summary, I think you're going to have to rework things to use one of those two for interprocess communications -- Queues seem like the logical choice to me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文