# 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>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jen-hsuan-hsieh.gitbook.io/python/chapter1notes-from-research/chapter-7-module/72common-module/722threading.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
