Используются ли в каких-либо встроенных модулях Python потоки?
Будет ли импортировать / использовать любую из встроенных в Python библиотек потоки без явного запроса?
2 ответа
multiprocessing
модуль и subprocess
модуль как спавн threading.Thead
внутренние объекты, чтобы помочь обработать ввод / вывод с процессами, которые они порождают.
В частности, multiprocessing.Pool
порождает три потока, как только вы его создаете:
class Pool(object):
'''
Class which supports an async version of the `apply()` builtin
'''
Process = Process
def __init__(self, processes=None, initializer=None, initargs=(),
maxtasksperchild=None):
... # Stuff we don't care about
self._worker_handler = threading.Thread(
target=Pool._handle_workers,
args=(self, )
)
self._worker_handler.daemon = True
self._worker_handler._state = RUN
self._worker_handler.start()
self._task_handler = threading.Thread(
target=Pool._handle_tasks,
args=(self._taskqueue, self._quick_put, self._outqueue, self._pool)
)
self._task_handler.daemon = True
self._task_handler._state = RUN
self._task_handler.start()
self._result_handler = threading.Thread(
target=Pool._handle_results,
args=(self._outqueue, self._quick_get, self._cache)
)
self._result_handler.daemon = True
self._result_handler._state = RUN
self._result_handler.start()
subprocess
порождает темы, когда вы звоните popen_object.communicate
, чтобы прочитать stdout / stderr из запущенного подпроцесса.
def _communicate(self, input):
stdout = None # Return
stderr = None # Return
if self.stdout:
stdout = []
stdout_thread = threading.Thread(target=self._readerthread,
args=(self.stdout, stdout))
stdout_thread.setDaemon(True)
stdout_thread.start()
if self.stderr:
stderr = []
stderr_thread = threading.Thread(target=self._readerthread,
args=(self.stderr, stderr))
stderr_thread.setDaemon(True)
stderr_thread.start()
редактировать
Марк Дикинсон отмечает, что concurrent.futures.ProcessPoolExecutor
также порождает поток, по причинам, аналогичным этому multiprocessing.Pool
(обработка ввода / вывода с помощью процессов порождения):
def _start_queue_management_thread(self):
# When the executor gets lost, the weakref callback will wake up
# the queue management thread.
def weakref_cb(_, q=self._result_queue):
q.put(None)
if self._queue_management_thread is None:
# Start the processes so that their sentinels are known.
self._adjust_process_count()
self._queue_management_thread = threading.Thread(
target=_queue_management_worker,
args=(weakref.ref(self, weakref_cb),
self._processes,
self._pending_work_items,
self._work_ids,
self._call_queue,
self._result_queue))
self._queue_management_thread.daemon = True
self._queue_management_thread.start()
Следующие модули импорта threading
указание на то, что "потоки" могут быть использованы (неявно или явно)
asyncio
decimal
functools
cookiejar
multiprocessing
queue
sched
subprocess
telnetlib
tempfile
trace
Методология
grep -r "thread" * | grep "import" | grep -v "test" | grep -v "Lib/threading"
в {python install path}/Lib
каталог.
Используемая методология заключалась в том, чтобы увидеть, появилась ли "нить" в результатах grep, и обработать результат, используя серию grep
s.
Поэтому возьмите этот ответ с щепоткой соли.