PyO3 / pyo3

Rust bindings for the Python interpreter
https://pyo3.rs
Apache License 2.0
12.06k stars 744 forks source link

Multiprocessing seems to erroneously fork bomb #4215

Open MolotovCherry opened 4 months ago

MolotovCherry commented 4 months ago

Bug Description

A simple and valid multiprocessing example for python fork bombs when run under pyo3.

You'll forgive me if I didn't try to run this example again to check that it properly executes. I don't want to get self-bombed again. But the basic idea seems to hold. It happened to me twice already. If this example doesn't work, you can still place it in a file and run that file from pyo3 (that's how I did it)

(This also happens even with freeze_support())

(auto-initialize feature is checked)

use pyo3::prelude::*;

fn main() -> PyResult<()> {
    let code = r#"
import multiprocessing
import time

def worker():
    print("Starting worker")
    time.sleep(5)
    print("Worker finished")

if __name__ == "__main__":
    processes = []

    for _ in range(5):
        p = multiprocessing.Process(target=worker)
        p.start()
        processes.append(p)

    for p in processes:
        p.join()
"#;

    Python::with_gil(|py| Python::run_bound(py, code, None, None))
}

Steps to Reproduce

  1. Run code using python command in terminal
  2. No problem. Works great like it should.
  3. Run code in pyo3
  4. Anguish in horror as your system gets fork bombed

Backtrace

No response

Your operating system and version

Windows 11 10.0.22631 Build 22631

Your Python version (python --version)

Python 3.12.2

Your Rust version (rustc --version)

rustc 1.78.0 (9b00956e5 2024-04-29)

Your PyO3 version

0.21.2

How did you install python? Did you use a virtualenv?

From website using installer

Additional Info

No response

alex commented 4 months ago

This isn't specific to pyo3, it's a limitation of the "spawn" multiprocessing method that's used on Windows. See https://docs.python.org/3/library/multiprocessing.html#the-spawn-and-forkserver-start-methods In particular, see "Safe importing of main module"

MolotovCherry commented 4 months ago

This isn't specific to pyo3, it's a limitation of the "spawn" multiprocessing method that's used on Windows. See https://docs.python.org/3/library/multiprocessing.html#the-spawn-and-forkserver-start-methods In particular, see "Safe importing of main module"

Is that not the case with my example? They suggest to use if __name__ == '__main__': which I also use

alex commented 4 months ago

Because you're not running the entire Python binary, what's required may be slightly different here.