diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst index 789a84b02d59d2..59509baec9b13a 100644 --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -1025,6 +1025,12 @@ Miscellaneous .. versionadded:: 3.8 +.. function:: main_process() + + Return the main :class:`Process` object. + + .. versionadded:: 3.10 + .. function:: freeze_support() Add support for when a program which uses :mod:`multiprocessing` has been diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index cd86c82caffc56..2b520dbdd74097 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -1242,6 +1242,13 @@ linecache When a module does not define ``__loader__``, fall back to ``__spec__.loader``. (Contributed by Brett Cannon in :issue:`42133`.) +multiprocessing +--------------- + +Add a new :func:`multiprocessing.main_process` function to access the main +process. +(Contributed by Zackery Spytz in :issue:`38520`.) + os -- diff --git a/Lib/multiprocessing/context.py b/Lib/multiprocessing/context.py index de8a264829dff3..663c767a8f3f02 100644 --- a/Lib/multiprocessing/context.py +++ b/Lib/multiprocessing/context.py @@ -37,6 +37,7 @@ class BaseContext(object): current_process = staticmethod(process.current_process) parent_process = staticmethod(process.parent_process) active_children = staticmethod(process.active_children) + main_process = staticmethod(process.main_process) def cpu_count(self): '''Returns the number of CPUs in the system''' diff --git a/Lib/multiprocessing/dummy/__init__.py b/Lib/multiprocessing/dummy/__init__.py index 6a1468609e347b..b2cee5b6f160df 100644 --- a/Lib/multiprocessing/dummy/__init__.py +++ b/Lib/multiprocessing/dummy/__init__.py @@ -64,6 +64,8 @@ def exitcode(self): Process = DummyProcess current_process = threading.current_thread current_process()._children = weakref.WeakKeyDictionary() +main_process = threading.main_thread + def active_children(): children = current_process()._children diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py index 271ba3fd325138..d436373d1868e7 100644 --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -8,7 +8,7 @@ # __all__ = ['BaseProcess', 'current_process', 'active_children', - 'parent_process'] + 'parent_process', 'main_process'] # # Imports @@ -54,6 +54,13 @@ def parent_process(): ''' return _parent_process + +def main_process(): + ''' + Return process object representing the main process + ''' + return _main_process + # # # @@ -419,7 +426,7 @@ def close(self): _parent_process = None -_current_process = _MainProcess() +_current_process = _main_process = _MainProcess() _process_counter = itertools.count(1) _children = set() del _MainProcess diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 8e4e0765d46809..7c1c53d6a15a4a 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -592,6 +592,18 @@ def test_active_children(self): p.join() self.assertNotIn(p, self.active_children()) + @classmethod + def _test_main_process(cls, conn): + conn.send(cls.main_process() is cls.current_process()) + + def test_main_process(self): + self.assertIs(self.main_process(), self.current_process()) + reader, writer = self.Pipe(duplex=False) + p = self.Process(target=self._test_main_process, args=(writer,)) + p.start() + p.join() + self.assertEqual(reader.recv(), False) + @classmethod def _test_recursion(cls, wconn, id): wconn.send(id) @@ -6144,6 +6156,7 @@ class ProcessesMixin(BaseMixin): current_process = staticmethod(multiprocessing.current_process) parent_process = staticmethod(multiprocessing.parent_process) active_children = staticmethod(multiprocessing.active_children) + main_process = staticmethod(multiprocessing.main_process) set_executable = staticmethod(multiprocessing.set_executable) Pool = staticmethod(multiprocessing.Pool) Pipe = staticmethod(multiprocessing.Pipe) @@ -6228,6 +6241,7 @@ class ThreadsMixin(BaseMixin): connection = multiprocessing.dummy.connection current_process = staticmethod(multiprocessing.dummy.current_process) active_children = staticmethod(multiprocessing.dummy.active_children) + main_process = staticmethod(multiprocessing.dummy.main_process) Pool = staticmethod(multiprocessing.dummy.Pool) Pipe = staticmethod(multiprocessing.dummy.Pipe) Queue = staticmethod(multiprocessing.dummy.Queue) diff --git a/Misc/NEWS.d/next/Library/2020-12-02-16-57-20.bpo-38520.bgN3rB.rst b/Misc/NEWS.d/next/Library/2020-12-02-16-57-20.bpo-38520.bgN3rB.rst new file mode 100644 index 00000000000000..7dc75f424d43dd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-12-02-16-57-20.bpo-38520.bgN3rB.rst @@ -0,0 +1,2 @@ +Add a :func:`multiprocessing.main_process` function to access the main +process.