Используются ли в каких-либо встроенных модулях 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указание на то, что "потоки" могут быть использованы (неявно или явно)

  1. asyncio
  2. decimal
  3. functools
  4. cookiejar
  5. multiprocessing
  6. queue
  7. sched
  8. subprocess
  9. telnetlib
  10. tempfile
  11. trace

Методология

grep -r "thread" * | grep "import" | grep -v "test" | grep -v "Lib/threading"

в {python install path}/Lib каталог.

Используемая методология заключалась в том, чтобы увидеть, появилась ли "нить" в результатах grep, и обработать результат, используя серию greps.

Поэтому возьмите этот ответ с щепоткой соли.

Другие вопросы по тегам