> For the complete documentation index, see [llms.txt](https://jen-hsuan-hsieh.gitbook.io/python/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jen-hsuan-hsieh.gitbook.io/python/chapter1notes-from-research/chapter-7-module/72common-module/722threading.md).

# 7.2.2.threading

* 1.Introduction
  * This module constructs higher-level threading interfaces on top of the lower level [thread](https://docs.python.org/2/library/thread.html#module-thread) module. See also the mutex and Queue modules.
* 2.Usage
  * 創建Thread的方式有兩種:
    * 1.創建一個類別並覆寫Threading.Thread:
      * 在此類別中的*init*()中傳入參數, 此參數通常是要讓thread執行的function, 呼叫super.*init*()&#x20;
      * 覆寫run(), 通常在這裡執行傳入的function
    * 2.直接呼叫Threading.Thread
  * 比較好的架構如下: ![](/files/-M4M0N2drHeWm0AX-6Oi)
    * -ThreadRunner-

      * 最上層的包裝, Thread的管理者:
        * 私有變數中有一個Thread pool, 可以是list或是dictionary
        * 提供addThreadWorker(), 以添加Thread(Worker)到Thread pool
        * 提供run(), 以啟動Thread pool中所有的Thread(Worker)

      ```
      class TheradRunner():
        def __init__(self):
            self.__threadPool = {}

        def addThreadWorker(self, worker, name):
            self.__threadPool.update({name:Thread(worker)})

        def run(self):
            for name, thread in self.__threadPool.items():
                thread.start()
            for name, thread in self.__threadPool.items():
                thread.join()
      ```
    * -Thread-

      * 繼承threading.Thread
        * 在*init*()中傳入Worker, 在這裡可以用[hasattr](http://www.cnblogs.com/cenyu/p/5713686.html)檢查woker的run()是否是[callable](http://www.pythontab.com/html/2013/hanshu_0125/169.html), 並用hasattr檢查worker的run是否存在
        * 在*init*()中呼叫super.*init*()
        * 覆寫run(), 通常在這裡執行傳入的function

      ```
      class Thread(threading.Thread):
        def __init__(self, workerClass):
            super().__init__()
            self.status = Status.Init
            if hasattr(workerClass, 'run') and callable(workerClass.run):
                self.__workerClass = workerClass
                self.exceptionMessage = None
            else:
                self.status = Status.Error
                self.exceptionMessage = 'Worker function error'

        def start(self):
            if Status.Init == self.status:
                 self.status = Status.Running
                 super().start()

       def run(self):
            try:
                self.__workerClass.run()
                self.status = Status.Success
            except Exception:
                self.exceptionMessage = traceback.format_exc()
                self.status = Status.Error
      ```
    * -Worker-

      * 提供run(), 真正要讓Thread作的事
      * 若有很多不同的事情分別要讓不同的thread執行, 則可以分別撰寫不同類別, 這些類別都需要繼承Worker

      ```
      class Worker():
        def run(self):
            pass
      ```

      ```
      class ReadLineWorker(Worker):
        def __init__(self, aHoldingZoneMap):
            self.__holdingZoneTableMap = aHoldingZoneMap

        def run(self):
            self.readLinesAndAttribute()
      ```
    * -製作新的thread-

      ```
      lineWorker = ReadLineWorker(holdingZoneTableMap)
      threadRunner.addThreadWorker(lineWorker, 'ReadLineWorker')
      threadRunner.run()
      ```
* 3.Reference
  * <https://docs.python.org/2/library/threading.html>
  * <http://sebastiandahlgren.se/2014/06/27/running-a-method-as-a-background-thread-in-python/>
  * <https://puremonkey2010.blogspot.tw/2012/07/python-python-threading.html>
