Skip to content

Commit dec115c

Browse files
committed
[GR-49557] Implement multiprocessing spawn backend
PullRequest: graalpython/3025
2 parents 28d3431 + 0031983 commit dec115c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1854
-353
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ language runtime. The main focus is on user-observable behavior of the engine.
1414
* Support installing some packages with native extensions on Windows. Simple packages like `ujson` or `kiwisolver` will now work when installed from a venv inside a Visual Studio command prompt.
1515
* Raise `KeyboardInterrupt` exception when the process is interrupted. Enabled only when using the launcher.
1616
* Add option `python.InitialLocale` to change the default locale. If not set, then Java Locale#getDefault is used.
17+
* `multiprocessing` module now uses the `spawn` method (creates new processes) by default. The formerly default method that uses threads and multiple Truffle contexts can be selected using `multiprocessing.set_start_method('graalpy')`.
1718

1819
## Version 23.1.0
1920
* Oracle GraalPy distributions (previously known as GraalPy Enterprise) are now available under the [GFTC license](https://www.oracle.com/downloads/licenses/graal-free-license.html). The community builds published on Github have been renamed to `graalpy-community-<version>-<os>-<arch>.tar.gz`.

graalpython/com.oracle.graal.python.test/src/tests/test_multiprocessing.py

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -37,41 +37,8 @@
3737
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3838
# SOFTWARE.
3939
import multiprocessing
40-
import sys
41-
import time
42-
from multiprocessing.connection import wait
43-
44-
45-
def test_wait_timeout():
46-
timeout = 3
47-
a, b = multiprocessing.Pipe()
48-
x, y = multiprocessing.connection.Pipe(False) # Truffle multiprocessing pipe
49-
for fds in [[a, b], [x, y], [a, b, x, y]]:
50-
start = time.monotonic()
51-
res = wait(fds, timeout)
52-
delta = time.monotonic() - start
53-
assert not res
54-
assert delta < timeout * 2
55-
assert delta > timeout / 2
5640

57-
58-
def test_wait():
59-
a, b = multiprocessing.Pipe()
60-
x, y = multiprocessing.connection.Pipe(False) # Truffle multiprocessing pipe
61-
a.send(42)
62-
res = wait([b, y], 3)
63-
assert res == [b], "res1"
64-
assert b.recv() == 42, "res2"
65-
y.send(33)
66-
res = wait([b, x], 3)
67-
assert res == [x], "res3"
68-
assert x.recv() == 33, "res4"
69-
a.send(1)
70-
y.send(2)
71-
res = wait([b, x], 3)
72-
assert set(res) == set([b, x])
73-
assert b.recv() == 1
74-
assert x.recv() == 2
41+
import sys
7542

7643

7744
def test_array_read():

graalpython/com.oracle.graal.python.test/src/tests/test_semlock.py renamed to graalpython/com.oracle.graal.python.test/src/tests/test_multiprocessing_graalpy.py

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
22
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33
#
44
# The Universal Permissive License (UPL), Version 1.0
@@ -36,11 +36,53 @@
3636
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3737
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3838
# SOFTWARE.
39+
import multiprocessing
40+
from multiprocessing.connection import wait
3941

40-
def test_SemLock_raises_on_non_string_name():
41-
from _multiprocessing import SemLock
42-
try :
43-
SemLock(kind=1, value=1, name={1:2}, maxvalue=1, unlink=1)
44-
except TypeError:
45-
raised = True
46-
assert raised
42+
import sys
43+
import time
44+
45+
if sys.implementation.name == 'graalpy':
46+
multiprocessing.set_start_method('graalpy', force=True)
47+
48+
49+
def test_SemLock_raises_on_non_string_name():
50+
from _multiprocessing_graalpy import SemLock
51+
try:
52+
SemLock(kind=1, value=1, name={1: 2}, maxvalue=1, unlink=1)
53+
except TypeError:
54+
pass
55+
else:
56+
assert False
57+
58+
59+
def test_wait_timeout():
60+
timeout = 3
61+
a, b = multiprocessing.Pipe()
62+
x, y = multiprocessing.connection.Pipe(False) # Truffle multiprocessing pipe
63+
for fds in [[a, b], [x, y], [a, b, x, y]]:
64+
start = time.monotonic()
65+
res = wait(fds, timeout)
66+
delta = time.monotonic() - start
67+
assert not res
68+
assert delta < timeout * 2
69+
assert delta > timeout / 2
70+
71+
72+
def test_wait():
73+
a, b = multiprocessing.Pipe()
74+
x, y = multiprocessing.connection.Pipe(False) # Truffle multiprocessing pipe
75+
a.send(42)
76+
res = wait([b, y], 3)
77+
assert res == [b], "res1"
78+
assert b.recv() == 42, "res2"
79+
y.send(33)
80+
res = wait([b, x], 3)
81+
assert res == [x], "res3"
82+
assert x.recv() == 33, "res4"
83+
a.send(1)
84+
y.send(2)
85+
res = wait([b, x], 3)
86+
assert set(res) == {b, x}
87+
assert b.recv() == 1
88+
assert x.recv() == 2

graalpython/com.oracle.graal.python.test/src/tests/test_tagged_unittests.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@
6464
(None, "arm", "test_smtplib"),
6565
(None, "aarch64", "test_imaplib"),
6666
(None, "arm", "test_multiprocessing_spawn"),
67+
(None, "arm", "test_multiprocessing_graalpy"),
6768
(None, "aarch64", "test_multiprocessing_spawn"),
69+
(None, "aarch64", "test_multiprocessing_graalpy"),
6870
)
6971

7072

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_concurrent_futures.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,31 @@
7070
*graalpython.lib-python.3.test.test_concurrent_futures.ProcessPoolSpawnProcessPoolShutdownTest.test_shutdown_no_wait
7171
*graalpython.lib-python.3.test.test_concurrent_futures.ProcessPoolSpawnProcessPoolShutdownTest.test_submit_after_interpreter_shutdown
7272
*graalpython.lib-python.3.test.test_concurrent_futures.ProcessPoolSpawnWaitTest.test_20369
73+
*graalpython.lib-python.3.test.test_concurrent_futures.ProcessPoolSpawnWaitTest.test_all_completed
74+
*graalpython.lib-python.3.test.test_concurrent_futures.ProcessPoolSpawnWaitTest.test_first_completed
7375
*graalpython.lib-python.3.test.test_concurrent_futures.ProcessPoolSpawnWaitTest.test_first_completed_some_already_completed
76+
*graalpython.lib-python.3.test.test_concurrent_futures.ProcessPoolSpawnWaitTest.test_first_exception
77+
*graalpython.lib-python.3.test.test_concurrent_futures.ProcessPoolSpawnWaitTest.test_first_exception_one_already_failed
78+
*graalpython.lib-python.3.test.test_concurrent_futures.ProcessPoolSpawnWaitTest.test_first_exception_some_already_complete
79+
*graalpython.lib-python.3.test.test_concurrent_futures.ProcessPoolSpawnWaitTest.test_timeout
80+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolAsCompletedTest.test_correct_timeout_exception_msg
81+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolAsCompletedTest.test_duplicate_futures
82+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolAsCompletedTest.test_no_timeout
83+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolAsCompletedTest.test_zero_timeout
84+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolExecutorTest.test_default_workers
85+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolExecutorTest.test_executor_map_current_future_cancel
86+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolExecutorTest.test_idle_thread_reuse
87+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolExecutorTest.test_map
88+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolExecutorTest.test_map_exception
89+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolExecutorTest.test_map_submits_without_iteration
90+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolExecutorTest.test_map_timeout
91+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolExecutorTest.test_max_workers_negative
92+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolExecutorTest.test_no_stale_references
93+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolExecutorTest.test_saturation
94+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolExecutorTest.test_shutdown_race_issue12456
95+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolExecutorTest.test_submit
96+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolExecutorTest.test_submit_keyword
97+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolFailingInitializerTest.test_initializer
98+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolInitializerTest.test_initializer
99+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolShutdownTest.test_cancel_futures
100+
*graalpython.lib-python.3.test.test_concurrent_futures.ThreadPoolShutdownTest.test_context_manager_shutdown

0 commit comments

Comments
 (0)