python - 在 Rust 中使用 python 的多处理库

标签 python rust cpython

我使用 Rust 来加速数据处理管道,但我必须按原样运行一些现有的 Python 代码,我想并行化这些代码。在另一个 question 中讨论,鉴于我的项目的特定约束,创建多个 Python 进程是一种可能的方法。但是,运行下面的代码会产生无限循环。我不太明白为什么。

use cpython::Python;

fn main() {
    let gil = Python::acquire_gil();
    let py = gil.python();
    py.run(r#"
import sys
from multiprocessing import Process

def f(name):
    print('hello', name)

if __name__ == '__main__':
    print('start')
    sys.argv=['']
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()
    "#, None,None).unwrap();
}

输出(一直持续到 Ctrl-C):
start
start
start
start
start
start
start
start

编辑

正如下面评论中提到的,我放弃了尝试从 Python 代码创建进程。 Windows、Python 多处理模块以及如何使用 Rust 创建进程之间的干扰太模糊而无法正确管理。
因此,我将从 Rust 创建和管理它们。因此,该代码更具教科书:
use std::process::Command;
fn main() {
    let mut cmd = Command::new("python");
    cmd.args(&["-c", "print('test')"]); 
    let process = cmd.spawn().expect("Couldn't spawn process.");
    println!("{:?}", process.wait_with_output().unwrap());
}

最佳答案

我无法重现这个;对我来说它只是打印start然后 hello bob正如预期的那样。无论出于何种原因,在您的情况下,__name__总是等于 "__main__"你得到这个无限递归。我在 Arch Linux 上使用 cpython crate 版本 v0.4.1 和 Python 3.8.1。

解决方法是不依赖 __name__完全没有,而是将您的 Python 代码定义为带有 main() 的模块。函数,然后调用该函数:

use cpython::{Python, PyModule};

fn main() {
    let gil = Python::acquire_gil();
    let py = gil.python();
    let module = PyModule::new(py, "bob").unwrap();
    py.run(r#"
import sys
from multiprocessing import Process

def f(name):
    print('hello', name)

def main():
    print('start')
    sys.argv=['']
    p = Process(target=f, args=('bob',))
    p.start()
    p.join()
    "#, Some(&module.dict(py)), None).unwrap();
    module.call(py, "main", cpython::NoArgs, None).unwrap();
}

关于python - 在 Rust 中使用 python 的多处理库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60391839/

相关文章:

python - 如何在 python 中获取 OpenAIobject 中的项目?

python - 为什么 Nodejs 可以做文件 I/O 异步而 Python asyncio 不能?

python - python 中的面向对象设计。上下?

python - scrapy项目中errback和callback中各种异常如何处理?

rust - 如何在结构中初始化这个数组数组?

multithreading - 在 Rayon 线程内调用 `Arc::new()` 会导致垃圾编译器错误

rust - 将未知类型转换为已知类型

python - CPython中函数对象和代码对象的关系

python - CPython 是否保证 dict.keys 与 dict.values 具有相同的顺序?

python - 为什么要使用虚拟插槽?