bpo-36867: Create the resource_tracker before launching SharedMemoryM… · python/cpython@b1dfcad (original) (raw)
`@@ -17,6 +17,7 @@
`
17
17
`import socket
`
18
18
`import random
`
19
19
`import logging
`
``
20
`+
import subprocess
`
20
21
`import struct
`
21
22
`import operator
`
22
23
`import pickle
`
`@@ -3765,6 +3766,27 @@ def test_shared_memory_SharedMemoryServer_ignores_sigint(self):
`
3765
3766
``
3766
3767
`smm.shutdown()
`
3767
3768
``
``
3769
`+
@unittest.skipIf(os.name != "posix", "resource_tracker is posix only")
`
``
3770
`+
def test_shared_memory_SharedMemoryManager_reuses_resource_tracker(self):
`
``
3771
`+
bpo-36867: test that a SharedMemoryManager uses the
`
``
3772
`+
same resource_tracker process as its parent.
`
``
3773
`+
cmd = '''if 1:
`
``
3774
`+
from multiprocessing.managers import SharedMemoryManager
`
``
3775
+
``
3776
+
``
3777
`+
smm = SharedMemoryManager()
`
``
3778
`+
smm.start()
`
``
3779
`+
sl = smm.ShareableList(range(10))
`
``
3780
`+
smm.shutdown()
`
``
3781
`+
'''
`
``
3782
`+
rc, out, err = test.support.script_helper.assert_python_ok('-c', cmd)
`
``
3783
+
``
3784
`+
Before bpo-36867 was fixed, a SharedMemoryManager not using the same
`
``
3785
`+
resource_tracker process as its parent would make the parent's
`
``
3786
`+
tracker complain about sl being leaked even though smm.shutdown()
`
``
3787
`+
properly released sl.
`
``
3788
`+
self.assertFalse(err)
`
``
3789
+
3768
3790
`def test_shared_memory_SharedMemoryManager_basics(self):
`
3769
3791
`smm1 = multiprocessing.managers.SharedMemoryManager()
`
3770
3792
`with self.assertRaises(ValueError):
`
`@@ -3904,8 +3926,6 @@ def test_shared_memory_ShareableList_pickling(self):
`
3904
3926
`sl.shm.close()
`
3905
3927
``
3906
3928
`def test_shared_memory_cleaned_after_process_termination(self):
`
3907
``
`-
import subprocess
`
3908
``
`-
from multiprocessing import shared_memory
`
3909
3929
`cmd = '''if 1:
`
3910
3930
` import os, time, sys
`
3911
3931
` from multiprocessing import shared_memory
`
`@@ -3916,18 +3936,29 @@ def test_shared_memory_cleaned_after_process_termination(self):
`
3916
3936
` sys.stdout.flush()
`
3917
3937
` time.sleep(100)
`
3918
3938
` '''
`
3919
``
`-
p = subprocess.Popen([sys.executable, '-E', '-c', cmd],
`
3920
``
`-
stdout=subprocess.PIPE)
`
3921
``
`-
name = p.stdout.readline().strip().decode()
`
``
3939
`+
with subprocess.Popen([sys.executable, '-E', '-c', cmd],
`
``
3940
`+
stdout=subprocess.PIPE,
`
``
3941
`+
stderr=subprocess.PIPE) as p:
`
``
3942
`+
name = p.stdout.readline().strip().decode()
`
3922
3943
``
3923
``
`-
killing abruptly processes holding reference to a shared memory
`
3924
``
`-
segment should not leak the given memory segment.
`
3925
``
`-
p.terminate()
`
3926
``
`-
p.wait()
`
3927
``
`-
time.sleep(1.0) # wait for the OS to collect the segment
`
``
3944
`+
killing abruptly processes holding reference to a shared memory
`
``
3945
`+
segment should not leak the given memory segment.
`
``
3946
`+
p.terminate()
`
``
3947
`+
p.wait()
`
``
3948
`+
time.sleep(1.0) # wait for the OS to collect the segment
`
3928
3949
``
3929
``
`-
with self.assertRaises(FileNotFoundError):
`
3930
``
`-
smm = shared_memory.SharedMemory(name, create=False)
`
``
3950
`+
The shared memory file was deleted.
`
``
3951
`+
with self.assertRaises(FileNotFoundError):
`
``
3952
`+
smm = shared_memory.SharedMemory(name, create=False)
`
``
3953
+
``
3954
`+
if os.name == 'posix':
`
``
3955
`+
A warning was emitted by the subprocess' own
`
``
3956
`+
resource_tracker (on Windows, shared memory segments
`
``
3957
`+
are released automatically by the OS).
`
``
3958
`+
err = p.stderr.read().decode()
`
``
3959
`+
self.assertIn(
`
``
3960
`+
"resource_tracker: There appear to be 1 leaked "
`
``
3961
`+
"shared_memory objects to clean up at shutdown", err)
`
3931
3962
``
3932
3963
`#
`
3933
3964
`#
`
`@@ -4560,7 +4591,7 @@ def run_in_child(cls):
`
4560
4591
`print(json.dumps(flags))
`
4561
4592
``
4562
4593
`def test_flags(self):
`
4563
``
`-
import json, subprocess
`
``
4594
`+
import json
`
4564
4595
`# start child process using unusual flags
`
4565
4596
`prog = ('from test._test_multiprocessing import TestFlags; ' +
`
4566
4597
`'TestFlags.run_in_child()')
`
`@@ -4866,7 +4897,6 @@ def test_resource_tracker(self):
`
4866
4897
`#
`
4867
4898
`# Check that killing process does not leak named semaphores
`
4868
4899
`#
`
4869
``
`-
import subprocess
`
4870
4900
`cmd = '''if 1:
`
4871
4901
` import time, os, tempfile
`
4872
4902
` import multiprocessing as mp
`