_multiprocessing_helpers.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. """Helper module to factorize the conditional multiprocessing import logic
  2. We use a distinct module to simplify import statements and avoid introducing
  3. circular dependencies (for instance for the assert_spawning name).
  4. """
  5. import os
  6. import warnings
  7. # Obtain possible configuration from the environment, assuming 1 (on)
  8. # by default, upon 0 set to None. Should instructively fail if some non
  9. # 0/1 value is set.
  10. mp = int(os.environ.get("JOBLIB_MULTIPROCESSING", 1)) or None
  11. if mp:
  12. try:
  13. import _multiprocessing # noqa
  14. import multiprocessing as mp
  15. except ImportError:
  16. mp = None
  17. # 2nd stage: validate that locking is available on the system and
  18. # issue a warning if not
  19. if mp is not None:
  20. try:
  21. # try to create a named semaphore using SemLock to make sure they are
  22. # available on this platform. We use the low level object
  23. # _multiprocessing.SemLock to avoid spawning a resource tracker on
  24. # Unix system or changing the default backend.
  25. import tempfile
  26. from _multiprocessing import SemLock
  27. _rand = tempfile._RandomNameSequence()
  28. for i in range(100):
  29. try:
  30. name = "/joblib-{}-{}".format(os.getpid(), next(_rand))
  31. _sem = SemLock(0, 0, 1, name=name, unlink=True)
  32. del _sem # cleanup
  33. break
  34. except FileExistsError as e: # pragma: no cover
  35. if i >= 99:
  36. raise FileExistsError("cannot find name for semaphore") from e
  37. except (FileExistsError, AttributeError, ImportError, OSError) as e:
  38. mp = None
  39. warnings.warn("%s. joblib will operate in serial mode" % (e,))
  40. # 3rd stage: backward compat for the assert_spawning helper
  41. if mp is not None:
  42. from multiprocessing.context import assert_spawning
  43. else:
  44. assert_spawning = None