Python入門進階教程-多線程與多進程

「關注我,和我一塊兒放下靈魂,讓靈魂去搬磚。」python

Python多線程與多進

Python版本3.8.0,開發工具:Pycharm正則表達式

試想一下當你有1w個小文件須要處理,假設每一個文件讀取處理到寫入須要1秒,編程

那麼你處理完因此文件會須要兩個多小時。bash

可是若是你能夠同時開啓四個任務處理1w 個文件,每一個任務平均處理2500個微信

這個時候你的時間能夠壓縮在一小時之內。網絡

如何同時對一個文件夾開啓四個任務同時處理不一樣的任務,而不會產生衝突,接下來咱們一塊兒瞭解一下多線程和多進程。多線程

進程與線程

從必定意義上講,進程就是一個應用程序在處理機上的一次執行過程,它是一個動態的概念,而線程是進程中的一部分,進程包含多個線程在運行。socket

==進程==是資源(CPU、內存等)分配的基本單位,它是程序執行時的一個實例。==線程==是程序執行時的最小單位,它是進程的一個執行流,是CPU調度和分派的基本單位,一個進程能夠由不少個線程組成,線程間共享進程的全部資源。ide

Python多線程

Python 中提供兩個標準庫 thread 和 threading 用於對線程的支持,但 Python3 中已放棄對 thread 的支持,因此接下來均以 threading 爲例。函數

Python中有兩種方式實現線程:

  • 1.實例化一個 threading.Thread 的對象,並傳入一個初始化函數對象做爲線程執行的入口;
  • 2.繼承 threading.Thread,並重寫 run 函數;
# 第一種實現線程的方法
import threading
# my_fun爲自定義函數,args爲自定義函數的參數
thread1 = threading.Thread(target=my_fun, args=('This is thread 1',))
thread2 = threading.Thread(target=my_fun, args=('This is thread 2',))
# 啓動線程
thread1.start()
thread2.start()


# 第二中實現線程的方法
class MyThread(threading.Thread):
    # step 1: call base __init__ function
    def __init__(self, thread_name):
        super(CustomThread, self).__init__(name=thread_name)
        self._tname = thread_name
    # step 2: overide run function
    def run(self):
        print("This is %s running...." % self._tname)
# 實例化MyThread
thread1 = MyThread("thread 1")
thread2 = MyThread("thread 2")
# 啓動線程
thread1.start()
thread2.start()

複製代碼

注:

  • 兩種方式建立線程,指定的參數最終都會傳給threading.Thread類;
  • 傳給線程的目標函數是在基類Thread的run函數體中被調用的,若是run沒有被重寫的話。

threading.Thread提供的線程對象方法和屬性:

1. start():建立線程後經過start啓動線程,等待CPU調度,爲run函數執行作準備;
2. run():線程開始執行的入口函數,函數體中會調用用戶編寫的target函數,或者執行被重載的run函數;
3. join([timeout]):阻塞掛起調用該函數的線程,直到被調用線程執行完成或超時。一般會在主線程中調用該方法,等待其餘線程執行完成。
4. name、getName()&setName():線程名稱相關的操做;
5. ident:整數類型的線程標識符,線程開始執行前(調用start以前)爲None;
6. isAlive()、is_alive():start函數執行以後到run函數執行完以前都爲True;
7. daemon、isDaemon()&setDaemon():守護線程相關。
複製代碼

Python多進程

Python 提供 multiprocessing 用於建立多進程

建立進程的方式和建立線程的方式相似:

  • 1.實例化一個 multiprocessing.Process 的對象,並傳入一個初始化函數對象做爲新建進程執行入口;
  • 2.繼承 multiprocessing.Process,並重寫 run 函數;
# 第一種實現進程的方法
from multiprocessing import Process

# my_fun爲自定義函數,args爲自定義函數的參數
process1 = Process(target=my_fun, args=('This is process 1',))
process2 = Process(target=my_fun, args=('This is process 2',))
# 啓動線程
process1.start()
process2.start()
# join()方法能夠等待子進程結束後再繼續往下運行,一般用於進程間的同步。
process1.join()
process2.join()


# 第二中實現進程的方法
from multiprocessing import Process  

class MyProcess(Process):
    def __init__(self, p_name, target=None):
        # step 1: call base __init__ function()
        super().__init__(name=p_name, target=target, args=(p_name,))

    def run(self):
        # step 2:
        print("Process name: %s, pid: %s " % (self.name, os.getpid()))

if __name__ == '__main__':
    # 實例化MyProcess
    process1 = MyProcess("process 1")
    process2 = MyProcess("process 2")
    # 啓動進程
    process1.start()
    process2.start()
    process1.join()
    process2.join()

複製代碼

進程 vs. 線程

是否採用多任務須要考慮任務的類型,咱們能夠把任務分爲CPU密集型和IO密集型。

  • CPU密集型任務的特色是要進行大量的計算,消耗CPU資源,好比計算圓周率、對視頻進行高清解碼等等,全靠CPU的運算能力。
  • 涉及到網絡、磁盤IO的任務都是IO密集型任務,這類任務的特色是CPU消耗不多,任務的大部分時間都在等待IO操做完成

總結:

  • CPU密集型:程序須要佔用CPU進行大量的運算和數據處理;
  • I/O密集型:程序中須要頻繁的進行I/O操做;例如網絡中socket數據傳輸和讀取等;

因爲python多線程並非並行執行,所以較適合與I/O密集型程序,多進程並行執行適用於CPU密集型程序;


根據任務的需求選擇相應的多任務方式,在多文件數據操做、爬蟲等任務時至關實用!


下節將介紹Python JSON操做


系列文章傳送門

Python入門進階教程-正則表達式

Python入門進階教程-面向對象

Python入門基礎彙總


Python系列

Python系列會持續更新,從基礎入門到進階技巧,從編程語法到項目實戰。若您在閱讀的過程當中發現文章存在錯誤,煩請指正,很是感謝;若您在閱讀的過程當中能有所收穫,歡迎一塊兒分享交流。

若是你也想和我一塊兒學習Python,能夠關注個人微信公衆號

學習Python,咱們不僅是說說而已

相關文章
相關標籤/搜索