2014-07-18 42 views
3

將導入/使用任何python的內置庫產生線程而不被明確詢問?是否有任何python內置模塊使用線程?

+1

在導入時創建線程應該很少;進口時產生的副作用通常被忽視。但是,似乎'import tkinter'在我的OS X機器上創建了一個新的線程。 –

+3

當然''進口反引力'開始一個新的*進程*! (如果您的網絡瀏覽器尚未運行。) –

回答

7

multiprocessing模塊和subprocess模塊都在內部產生threading.Thead對象以幫助處理它們產生的進程的I/O。

具體來說,multiprocessing.Poolspawns three threads只要你實例化它:

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生成線程when you call popen_object.communicate,從運行子讀取標準輸出/標準錯誤。

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() 

編輯

Mark Dickinson points outconcurrent.futures.ProcessPoolExecutor還產生一個線程,爲類似於multiprocessing.Pool原因(處理I/O與產卵過程):

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() 
+0

對於Python 3,'concurrent.futures'和'asyncio'可能值得一提。 –

+0

@MarkDickinson就我所知,使用'concurrent.futures'你總是明確地要求一個線程(例如使用'ThreadExecutor')。我不認爲'asyncio'創建任何線程;它只是有能力與'concurrent.futures.ThreadExecutor'集成。當您沒有明確詢問時,OP專門尋找使用線程的地方。 – dano

+1

是的,我想這取決於「明確」是如何明確的。一個帶有'concurrent.futures'的稍微隱藏的例子就是創建一個'ProcessPoolExecutor':當你第一次向它提交一個工作時,你會在你的主進程中得到一些額外的線程(這要感謝你使用'multiprocessing'機制已經確定,所以也許這不算)。同意'asyncio'。 –

5

下列模塊進口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結果中是否出現「線程」,並使用一系列grep來處理結果。

所以拿一點鹽的這個答案。

+0

是的,其中大部分只是導入它來獲得同步原語。我認爲唯一一個實際產生的線程在我的回答中沒有提到,它是'telnetlib',它使用'thread.start_new_thread'而不是'threading'模塊。但是隻有在你明確地用'mt_interact'(意思是多線程交互)來提問的時候纔會這樣做。 – dano

相關問題