Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

bpo-36668: FIX reuse semaphore tracker for child processes#5172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
pitrou merged 12 commits intopython:masterfromtomMoral:PR_fix_semtracker
Apr 24, 2019
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
12 commits
Select commitHold shift + click to select a range
d77cd4a
FIX reuse semaphore tracker for child processes
tomMoralJan 13, 2018
398216f
FIX typo in spawn.prepare
tomMoralFeb 24, 2018
87964fc
TST add test for reused semtracker + CLN unused code
tomMoralApr 6, 2018
49e96f1
DOC add what's new
tomMoralApr 6, 2018
d9b23e1
ENH test check pid of semaphore_tracker
tomMoralMar 15, 2019
b61bba2
FIX dangling process in test_sem_tracker
tomMoralMar 17, 2019
96cb643
CLN correctly avoid dangling processes
tomMoralMar 18, 2019
cbfefd1
CLN improve docstring for _check_alive in semaphore_tracker
ZackerySpytzApr 11, 2019
8f8e82f
CLN improve tests and avoid passing unused variables
tomMoralApr 19, 2019
9a5c94e
FIX semaphore_tracker for the fork context
tomMoralApr 19, 2019
ada8a9d
ENH more robust sem_tracker.ensure_running
tomMoralApr 24, 2019
f6d6a31
DBG trigger appveyor
tomMoralApr 24, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletionsLib/multiprocessing/semaphore_tracker.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -44,20 +44,23 @@ def ensure_running(self):
This can be run from any process. Usually a child process will use
the semaphore created by its parent.'''
with self._lock:
if self._pid is not None:
if self._fd is not None:
# semaphore tracker was launched before, is it still running?
if self._check_alive():
# => still alive
return
# => dead, launch it again
os.close(self._fd)

# Clean-up to avoid dangling processes.
try:
pid, _ = os.waitpid(self._pid, os.WNOHANG)
# _pid can be None if this process is a child from another
# python process, which has started the semaphore_tracker.
if self._pid is not None:
os.waitpid(self._pid, 0)
except ChildProcessError:
# Theprocessterminated
# Thesemaphore_tracker has already beenterminated.
pass
else:
if not pid:
# => still alive
return

# => dead, launch it again
os.close(self._fd)
self._fd = None
self._pid = None

Expand DownExpand Up@@ -99,6 +102,17 @@ def ensure_running(self):
finally:
os.close(r)

def _check_alive(self):
'''Check that the pipe has not been closed by sending a probe.'''
try:
# We cannot use send here as it calls ensure_running, creating
# a cycle.
os.write(self._fd, b'PROBE:0\n')
except OSError:
return False
else:
return True

def register(self, name):
'''Register name of semaphore with semaphore tracker.'''
self._send('REGISTER', name)
Expand DownExpand Up@@ -150,6 +164,8 @@ def main(fd):
cache.add(name)
elif cmd == b'UNREGISTER':
cache.remove(name)
elif cmd == b'PROBE':
pass
else:
raise RuntimeError('unrecognized command %r' % cmd)
except Exception:
Expand Down
28 changes: 28 additions & 0 deletionsLib/test/_test_multiprocessing.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4895,6 +4895,34 @@ def test_semaphore_tracker_sigkill(self):
# Uncatchable signal.
self.check_semaphore_tracker_death(signal.SIGKILL, True)

@staticmethod
def _is_semaphore_tracker_reused(conn, pid):
from multiprocessing.semaphore_tracker import _semaphore_tracker
_semaphore_tracker.ensure_running()
# The pid should be None in the child process, expect for the fork
# context. It should not be a new value.
reused = _semaphore_tracker._pid in (None, pid)
reused &= _semaphore_tracker._check_alive()
conn.send(reused)

def test_semaphore_tracker_reused(self):
from multiprocessing.semaphore_tracker import _semaphore_tracker
_semaphore_tracker.ensure_running()
pid = _semaphore_tracker._pid

r, w = multiprocessing.Pipe(duplex=False)
p = multiprocessing.Process(target=self._is_semaphore_tracker_reused,
args=(w, pid))
p.start()
is_semaphore_tracker_reused = r.recv()

# Clean up
p.join()
w.close()
r.close()

self.assertTrue(is_semaphore_tracker_reused)


class TestSimpleQueue(unittest.TestCase):

Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
Fix the multiprocessing.semaphore_tracker so it is reused by child processes

[8]ページ先頭

©2009-2026 Movatter.jp