Skip to content

Commit ea53051

Browse files
authored
Use spawn start method in multiprocessing programs (#11391)
* Use `spawn` start method in multiprocessing programs * Set `spawn` start method in doctest * Use `with` statement for locks * Pass multiprocessing context explicitly
1 parent 5131e31 commit ea53051

File tree

1 file changed

+53
-26
lines changed

1 file changed

+53
-26
lines changed

Diff for: sorts/odd_even_transposition_parallel.py

+53-26
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
synchronization could be used.
1212
"""
1313

14-
from multiprocessing import Lock, Pipe, Process
14+
import multiprocessing as mp
1515

1616
# lock used to ensure that two processes do not access a pipe at the same time
1717
# NOTE This breaks testing on build runner. May work better locally
18-
# process_lock = Lock()
18+
# process_lock = mp.Lock()
1919

2020
"""
2121
The function run by the processes that sorts the list
@@ -29,36 +29,41 @@
2929
"""
3030

3131

32-
def oe_process(position, value, l_send, r_send, lr_cv, rr_cv, result_pipe):
33-
process_lock = Lock()
32+
def oe_process(
33+
position,
34+
value,
35+
l_send,
36+
r_send,
37+
lr_cv,
38+
rr_cv,
39+
result_pipe,
40+
multiprocessing_context,
41+
):
42+
process_lock = multiprocessing_context.Lock()
3443

3544
# we perform n swaps since after n swaps we know we are sorted
3645
# we *could* stop early if we are sorted already, but it takes as long to
3746
# find out we are sorted as it does to sort the list with this algorithm
3847
for i in range(10):
3948
if (i + position) % 2 == 0 and r_send is not None:
4049
# send your value to your right neighbor
41-
process_lock.acquire()
42-
r_send[1].send(value)
43-
process_lock.release()
50+
with process_lock:
51+
r_send[1].send(value)
4452

4553
# receive your right neighbor's value
46-
process_lock.acquire()
47-
temp = rr_cv[0].recv()
48-
process_lock.release()
54+
with process_lock:
55+
temp = rr_cv[0].recv()
4956

5057
# take the lower value since you are on the left
5158
value = min(value, temp)
5259
elif (i + position) % 2 != 0 and l_send is not None:
5360
# send your value to your left neighbor
54-
process_lock.acquire()
55-
l_send[1].send(value)
56-
process_lock.release()
61+
with process_lock:
62+
l_send[1].send(value)
5763

5864
# receive your left neighbor's value
59-
process_lock.acquire()
60-
temp = lr_cv[0].recv()
61-
process_lock.release()
65+
with process_lock:
66+
temp = lr_cv[0].recv()
6267

6368
# take the higher value since you are on the right
6469
value = max(value, temp)
@@ -94,39 +99,60 @@ def odd_even_transposition(arr):
9499
>>> odd_even_transposition(unsorted_list) == sorted(unsorted_list + [1])
95100
False
96101
"""
102+
# spawn method is considered safer than fork
103+
multiprocessing_context = mp.get_context("spawn")
104+
97105
process_array_ = []
98106
result_pipe = []
99107
# initialize the list of pipes where the values will be retrieved
100108
for _ in arr:
101-
result_pipe.append(Pipe())
109+
result_pipe.append(multiprocessing_context.Pipe())
102110
# creates the processes
103111
# the first and last process only have one neighbor so they are made outside
104112
# of the loop
105-
temp_rs = Pipe()
106-
temp_rr = Pipe()
113+
temp_rs = multiprocessing_context.Pipe()
114+
temp_rr = multiprocessing_context.Pipe()
107115
process_array_.append(
108-
Process(
116+
multiprocessing_context.Process(
109117
target=oe_process,
110-
args=(0, arr[0], None, temp_rs, None, temp_rr, result_pipe[0]),
118+
args=(
119+
0,
120+
arr[0],
121+
None,
122+
temp_rs,
123+
None,
124+
temp_rr,
125+
result_pipe[0],
126+
multiprocessing_context,
127+
),
111128
)
112129
)
113130
temp_lr = temp_rs
114131
temp_ls = temp_rr
115132

116133
for i in range(1, len(arr) - 1):
117-
temp_rs = Pipe()
118-
temp_rr = Pipe()
134+
temp_rs = multiprocessing_context.Pipe()
135+
temp_rr = multiprocessing_context.Pipe()
119136
process_array_.append(
120-
Process(
137+
multiprocessing_context.Process(
121138
target=oe_process,
122-
args=(i, arr[i], temp_ls, temp_rs, temp_lr, temp_rr, result_pipe[i]),
139+
args=(
140+
i,
141+
arr[i],
142+
temp_ls,
143+
temp_rs,
144+
temp_lr,
145+
temp_rr,
146+
result_pipe[i],
147+
multiprocessing_context,
148+
),
123149
)
124150
)
125151
temp_lr = temp_rs
126152
temp_ls = temp_rr
127153

128154
process_array_.append(
129-
Process(
155+
multiprocessing_context.Process(
130156
target=oe_process,
131157
args=(
132158
len(arr) - 1,
@@ -136,6 +162,7 @@ def odd_even_transposition(arr):
136162
temp_lr,
137163
None,
138164
result_pipe[len(arr) - 1],
165+
multiprocessing_context,
139166
),
140167
)
141168
)

0 commit comments

Comments
 (0)