Skip to content

Commit 3ec91f0

Browse files
committed
fix: subinterpreter sporadic segmentation fault
1 parent 0ca68d5 commit 3ec91f0

2 files changed

Lines changed: 50 additions & 10 deletions

File tree

include/subint/base_subint.hpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@ class base_subint {
2424
int svc_init() {
2525
TIMESTART(svc_init_start_time);
2626

27+
// associate a new thread state with fastflow node's thread
28+
PyThreadState* main_tstate = PyThreadState_New(tstate->interp);
29+
2730
// Hold the main GIL
28-
PyEval_RestoreThread(tstate);
31+
PyEval_RestoreThread(main_tstate);
2932

3033
// Load pickling/unpickling functions but in the main interpreter
3134
pickling pickling_main;
@@ -43,9 +46,6 @@ class base_subint {
4346
// Cleanup of objects created
4447
pickling_main.~pickling();
4548

46-
// associate a new thread state with fastflow node's thread
47-
tstate = PyThreadState_New(tstate->interp);
48-
4949
TIMESTART(svc_init_create_interpr);
5050

5151
// Create a new sub-interpreter with its own GIL
@@ -59,21 +59,22 @@ class base_subint {
5959
.gil = PyInterpreterConfig_OWN_GIL,
6060
};
6161
// save thread state with main interpreter
62-
PyThreadState* cached_tstate = tstate;
62+
PyThreadState* interp_tstate;
6363
// create subinterpreter (and drop the main GIL and acquire the new GIL)
64-
PyStatus status = Py_NewInterpreterFromConfig(&tstate, &sub_interp_config);
64+
PyStatus status = Py_NewInterpreterFromConfig(&interp_tstate, &sub_interp_config);
6565
/* The new interpreter is now active in the current thread */
6666
if (PyStatus_Exception(status)) {
6767
PRINT_ERROR("Py_NewInterpreterFromConfig failure")
6868
// cleanup thread state with main interpreter
69-
PyThreadState_Clear(cached_tstate);
70-
PyThreadState_Delete(cached_tstate);
69+
PyThreadState_Clear(main_tstate);
70+
PyThreadState_Delete(main_tstate);
7171
return -1;
7272
}
7373

74+
tstate = interp_tstate;
7475
// cleanup thread state with main interpreter
75-
PyThreadState_Clear(cached_tstate);
76-
PyThreadState_Delete(cached_tstate);
76+
PyThreadState_Clear(main_tstate);
77+
PyThreadState_Delete(main_tstate);
7778

7879
LOGELAPSED("svc_init_create_interpr time ", svc_init_create_interpr);
7980

thesis/spawninterps.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from threading import Thread
2+
import _xxsubinterpreters as subinterpreters
3+
import time
4+
5+
def spawn_in_parallel():
6+
def spawn_sub():
7+
sid = subinterpreters.create(isolated=True)
8+
#subinterpreters.run_string(sid, "")
9+
#subinterpreters.destroy(sid)
10+
11+
threads = []
12+
for _ in range(100):
13+
t = Thread(target=spawn_sub)
14+
t.start()
15+
threads.append(t)
16+
17+
for t in threads:
18+
t.join()
19+
20+
def bench_subinterpreters():
21+
def spawn_sub():
22+
for _ in range(100):
23+
sid = subinterpreters.create(isolated=True)
24+
subinterpreters.run_string(sid, "")
25+
subinterpreters.destroy(sid)
26+
27+
28+
t = Thread(target=spawn_sub)
29+
t.start()
30+
t.join()
31+
32+
33+
if __name__ == "__main__":
34+
start = time.clock_gettime(time.CLOCK_MONOTONIC)
35+
36+
spawn_in_parallel()
37+
38+
end = time.clock_gettime(time.CLOCK_MONOTONIC)
39+
print("spawn_in_parallel", ((end - start)))

0 commit comments

Comments
 (0)