亚洲综合原千岁中文字幕_国产精品99久久久久久久vr_无码人妻aⅴ一区二区三区浪潮_成人h动漫精品一区二区三

主頁 > 知識庫 > 分析詳解python多線程與多進程區別

分析詳解python多線程與多進程區別

熱門標簽:哈爾濱外呼系統代理商 獲客智能電銷機器人 南昌辦理400電話怎么安裝 湛江電銷防封卡 鄭州智能外呼系統運營商 不錯的400電話辦理 佛山防封外呼系統收費 徐州天音防封電銷卡 電話機器人適用業務

python的多線程比較雞肋,優先使用多進程

1 基礎知識

現在的 PC 都是多核的,使用多線程能充分利用 CPU 來提供程序的執行效率。

1.1 線程

線程是一個基本的 CPU 執行單元。它必須依托于進程存活。一個線程是一個execution context(執行上下文),即一個 CPU 執行時所需要的一串指令。

1.2 進程

進程是指一個程序在給定數據集合上的一次執行過程,是系統進行資源分配和運行調用的獨立單位。可以簡單地理解為操作系統中正在執行的程序。也就說,每個應用程序都有一個自己的進程。

每一個進程啟動時都會最先產生一個線程,即主線程。然后主線程會再創建其他的子線程

1.3 兩者的區別

  • 線程必須在某個進行中執行。
  • 一個進程可包含多個線程,其中有且只有一個主線程。
  • 多線程共享同個地址空間、打開的文件以及其他資源。
  • 多進程共享物理內存、磁盤、打印機以及其他資源。

2 Python 多進程

2.1 創建多進程

Python 要進行多進程操作,需要用到muiltprocessing庫,其中的Process類跟threading模塊的Thread類很相似。所以直接看代碼熟悉多進程。

方法1:直接使用Process

代碼如下:

from multiprocessing import Process  
def show(name):
    print("Process name is " + name)
if __name__ == "__main__": 
    proc = Process(target=show, args=('subprocess',))  
    proc.start()  
    proc.join()

方法2:繼承Process來自定義進程類,重寫run方法

代碼如下:

from multiprocessing import Process
import time
class MyProcess(Process):
    def __init__(self, name):
        super(MyProcess, self).__init__()
        self.name = name
    def run(self):
        print('process name :' + str(self.name))
        time.sleep(1)
if __name__ == '__main__':
    for i in range(3):
        p = MyProcess(i)
        p.start()
    for i in range(3):
        p.join()

2.2 多進程通信

進程之間不共享數據的。如果進程之間需要進行通信,則要用到Queue模塊或者Pipi模塊來實現。

Queue

Queue 是多進程安全的隊列,可以實現多進程之間的數據傳遞。它主要有兩個函數,put和get。

put() 用以插入數據到隊列中,put 還有兩個可選參數:blocked 和 timeout。如果 blocked 為 True(默認值),并且 timeout 為正值,該方法會阻塞 timeout 指定的時間,直到該隊列有剩余的空間。如果超時,會拋出 Queue.Full 異常。如果 blocked 為 False,但該 Queue 已滿,會立即拋出 Queue.Full 異常。

get()可以從隊列讀取并且刪除一個元素。同樣,get 有兩個可選參數:blocked 和 timeout。如果 blocked 為 True(默認值),并且 timeout 為正值,那么在等待時間內沒有取到任何元素,會拋出 Queue.Empty 異常。如果blocked 為 False,有兩種情況存在,如果 Queue 有一個值可用,則立即返回該值,否則,如果隊列為空,則立即拋出 Queue.Empty 異常。

具體用法如下:

from multiprocessing import Process, Queue
 def put(queue):
    queue.put('Queue 用法')
 if __name__ == '__main__':
    queue = Queue()
    pro = Process(target=put, args=(queue,))
    pro.start()
    print(queue.get())   
    pro.join()

Pipe

Pipe的本質是進程之間的用管道數據傳遞,而不是數據共享,這和socket有點像。pipe() 返回兩個連接對象分別表示管道的兩端,每端都有send() 和recv()函數。

如果兩個進程試圖在同一時間的同一端進行讀取和寫入那么,這可能會損壞管道中的數據。

具體用法如下:

from multiprocessing import Process, Pipe
 def show(conn):
    conn.send('Pipe 用法')
    conn.close()
 if __name__ == '__main__':
    parent_conn, child_conn = Pipe() 
    pro = Process(target=show, args=(child_conn,))
    pro.start()
    print(parent_conn.recv())   
    pro.join()

2.3 進程池

創建多個進程,我們不用傻傻地一個個去創建。我們可以使用Pool模塊來搞定。

Pool 常用的方法如下:

具體用法見示例代碼:

from multiprocessing import Pool
def show(num):
    print('num : ' + str(num))
if __name__=="__main__":
    pool = Pool(processes = 3)
    for i in xrange(6):
        # 維持執行的進程總數為processes,當一個進程執行完畢后會添加新的進程進去
        pool.apply_async(show, args=(i, ))       
    print('======  apply_async  ======')
    pool.close()
    #調用join之前,先調用close函數,否則會出錯。執行完close后不會有新的進程加入到pool,join函數等待所有子進程結束
    pool.join()

3 Python 多線程

3.1 GIL

其他語言,CPU 是多核時是支持多個線程同時執行。但在 Python 中,無論是單核還是多核,同時只能由一個線程在執行。其根源是 GIL 的存在。

GIL 的全稱是 Global Interpreter Lock(全局解釋器鎖),來源是 Python 設計之初的考慮,為了數據安全所做的決定。某個線程想要執行,必須先拿到 GIL,我們可以把 GIL 看作是“通行證”,并且在一個 Python 進程中,GIL 只有一個。拿不到通行證的線程,就不允許進入 CPU 執行。

而目前 Python 的解釋器有多種,例如:

  • CPython:CPython 是用C語言實現的 Python 解釋器。 作為官方實現,它是最廣泛使用的 Python 解釋器。
  • PyPy:PyPy 是用RPython實現的解釋器。RPython 是 Python 的子集, 具有靜態類型。這個解釋器的特點是即時編譯,支持多重后端(C, CLI, JVM)。PyPy 旨在提高性能,同時保持最大兼容性(參考 CPython 的實現)。J
  • ython:Jython 是一個將 Python 代碼編譯成 Java 字節碼的實現,運行在JVM (Java Virtual Machine) 上。另外,它可以像是用 Python 模塊一樣,導入 并使用任何Java類。IronPython:IronPython 是一個針對 .NET 框架的 Python 實現。它 可以用 Python 和 .NET framewor k的庫,也能將 Python 代碼暴露給 .NET 框架中的其他語言。

GIL 只在 CPython 中才有,而在 PyPy 和 Jython 中是沒有 GIL 的。
每次釋放 GIL鎖,線程進行鎖競爭、切換線程,會消耗資源。這就導致打印線程執行時長,會發現耗時更長的原因。

3.2 創建多線程

Python提供兩個模塊進行多線程的操作,分別是thread和threading,

前者是比較低級的模塊,用于更底層的操作,一般應用級別的開發不常用。

方法1:直接使用threading.Thread()

import threading
# 這個函數名可隨便定義
def run(n):
    print("current task:", n)
if __name__ == "__main__":
    t1 = threading.Thread(target=run, args=("thread 1",))
    t2 = threading.Thread(target=run, args=("thread 2",))
    t1.start()
    t2.start()

方法2:繼承threading.Thread來自定義線程類,重寫run方法

import threading
class MyThread(threading.Thread):
    def __init__(self, n):
        super(MyThread, self).__init__()  # 重構run函數必須要寫
        self.n = n
    def run(self):
        print("current task:", n)
if __name__ == "__main__":
    t1 = MyThread("thread 1")
    t2 = MyThread("thread 2")
    t1.start()
    t2.start()

3.3 線程合并

Join函數執行順序是逐個執行每個線程,執行完畢后繼續往下執行。主線程結束后,子線程還在運行,join函數使得主線程等到子線程結束時才退出。

import threading
def count(n):
    while n > 0:
        n -= 1
if __name__ == "__main__":
    t1 = threading.Thread(target=count, args=("100000",))
    t2 = threading.Thread(target=count, args=("100000",))
    t1.start()
    t2.start()
    # 將 t1 和 t2 加入到主線程中
    t1.join()
    t2.join()

3.4 線程同步與互斥鎖

線程之間數據共享的。當多個線程對某一個共享數據進行操作時,就需要考慮到線程安全問題。threading模塊中定義了Lock 類,提供了互斥鎖的功能來保證多線程情況下數據的正確性。

用法的基本步驟:

#創建鎖
mutex = threading.Lock()
#鎖定
mutex.acquire([timeout])
#釋放
mutex.release()

其中,鎖定方法acquire可以有一個超時時間的可選參數timeout。如果設定了timeout,則在超時后通過返回值可以判斷是否得到了鎖,從而可以進行一些其他的處理。

具體用法見示例代碼:

import threading
import time
num = 0
mutex = threading.Lock()
class MyThread(threading.Thread):
    def run(self):
        global num 
        time.sleep(1)
        if mutex.acquire(1):  
            num = num + 1
            msg = self.name + ': num value is ' + str(num)
            print(msg)
            mutex.release()
if __name__ == '__main__':
    for i in range(5):
        t = MyThread()
        t.start()

3.5 可重入鎖(遞歸鎖)

為了滿足在同一線程中多次請求同一資源的需求,Python 提供了可重入鎖(RLock)。
RLock內部維護著一個Lock和一個counter變量,counter 記錄了 acquire 的次數,從而使得資源可以被多次 require。直到一個線程所有的 acquire 都被 release,其他的線程才能獲得資源。

具體用法如下:

#創建 RLock
mutex = threading.RLock()
class MyThread(threading.Thread):
    def run(self):
        if mutex.acquire(1):
            print("thread " + self.name + " get mutex")
            time.sleep(1)
            mutex.acquire()
            mutex.release()
            mutex.release()

3.6 守護線程

如果希望主線程執行完畢之后,不管子線程是否執行完畢都隨著主線程一起結束。我們可以使用setDaemon(bool)函數,它跟join函數是相反的。它的作用是設置子線程是否隨主線程一起結束,必須在start() 之前調用,默認為False。

3.7 定時器

如果需要規定函數在多少秒后執行某個操作,需要用到Timer類。具體用法如下:

from threading import Timer 
def show():
    print("Pyhton")
# 指定一秒鐘之后執行 show 函數
t = Timer(1, hello)
t.start()  

4 選擇多線程還是多進程?

在這個問題上,首先要看下你的程序是屬于哪種類型的。一般分為兩種 CPU 密集型 和 I/O 密集型。

  • CPU 密集型:程序比較偏重于計算,需要經常使用 CPU 來運算。例如科學計算的程序,機器學習的程序等。
  • I/O 密集型:顧名思義就是程序需要頻繁進行輸入輸出操作。爬蟲程序就是典型的 I/O 密集型程序。

如果程序是屬于 CPU 密集型,建議使用多進程。而多線程就更適合應用于 I/O 密集型程序。

以上就是分析詳解python多線程與多進程區別的詳細內容,更多關于python多線程與多進程區別的資料請關注腳本之家其它相關文章!

您可能感興趣的文章:
  • 手把手帶你了解python多進程,多線程
  • Python多進程共享numpy 數組的方法
  • 總結python多進程multiprocessing的相關知識
  • Python多線程與多進程相關知識總結
  • python實現多進程并發控制Semaphore與互斥鎖LOCK
  • python 多進程和多線程使用詳解
  • python 實現多進程日志輪轉ConcurrentLogHandler
  • Python多進程與多線程的使用場景詳解
  • python多進程執行方法apply_async使用說明
  • Python 多進程原理及實現
  • python多線程和多進程關系詳解
  • Python多進程的使用詳情

標簽:吉安 懷化 蕪湖 呂梁 蘭州 廣西 紹興 安康

巨人網絡通訊聲明:本文標題《分析詳解python多線程與多進程區別》,本文關鍵詞  分析,詳解,python,多,線程,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《分析詳解python多線程與多進程區別》相關的同類信息!
  • 本頁收集關于分析詳解python多線程與多進程區別的相關信息資訊供網民參考!
  • 推薦文章
    成人免费观看网欧美片| 超级乱淫黄漫画免费| 午夜欧美成人久久久久久| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 九九干| 91麻豆精品国产自产在线观看一区| 国产一区免费观看| 日韩一级精品视频在线观看| 成人av在线播放| 精品国产一区二区三区久久久蜜臀| 国产麻豆精品| 四虎影视久久| 欧美另类videosbestsex高清| 日日日夜夜操| 久久久成人网| 你懂的国产精品| 亚欧成人乱码一区二区| 成人免费观看网欧美片| 日韩中文字幕一区二区不卡| 四虎影视久久久| 久久国产精品自由自在| 日本特黄特色aa大片免费| 91麻豆国产级在线| 欧美一级视频免费观看| 日韩专区一区| 精品国产一区二区三区免费| 亚洲 男人 天堂| 日韩中文字幕一区二区不卡| 四虎久久影院| 精品视频一区二区三区| 一级女人毛片人一女人| 国产91精品露脸国语对白| 精品国产香蕉伊思人在线又爽又黄| 日本伦理片网站| 深夜做爰性大片中文| 香蕉视频一级| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 日本免费区| 韩国毛片 免费| 99热精品在线| 久久成人综合网| 免费的黄色小视频| 亚洲精品久久久中文字| 国产a网| 欧美激情一区二区三区视频| 天天做日日爱| 免费一级片在线观看| 国产视频一区在线| 欧美电影免费| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 色综合久久天天综合绕观看| 国产亚洲免费观看| 欧美电影免费看大全| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 亚洲第一色在线| 成人免费网站久久久| 欧美一级视频免费观看| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 国产a毛片| 午夜家庭影院| 精品视频在线观看视频免费视频| 九九久久国产精品大片| 日韩在线观看免费| 免费国产一级特黄aa大片在线| 91麻豆国产级在线| 日本特黄特色aaa大片免费| 精品国产一区二区三区免费| 精品国产一区二区三区国产馆| 天天色色色| 九九免费精品视频| 青青青草视频在线观看| 人人干人人草| 国产不卡精品一区二区三区| 免费毛片基地| 午夜欧美福利| 国产网站免费观看| 日韩免费在线观看视频| 99久久精品国产高清一区二区| 成人高清视频免费观看| 精品视频免费看| 成人免费网站视频ww| 欧美1区| 国产a毛片| 国产成人精品在线| 国产不卡福利| 国产a毛片| 黄色免费网站在线| 亚洲天堂在线播放| 精品国产香蕉在线播出| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 一级毛片视频在线观看| 九九干| 亚欧成人乱码一区二区| 青草国产在线| 国产a视频| 国产成人啪精品视频免费软件| 四虎精品在线观看| 日韩中文字幕一区| 毛片高清| 欧美1卡一卡二卡三新区| 久久成人综合网| 亚洲 国产精品 日韩| 国产精品123| 欧美激情在线精品video| 国产一区二区精品久| 四虎影视久久久| 亚洲精品久久玖玖玖玖| 日日日夜夜操| 九九免费高清在线观看视频| 日韩一级黄色| 国产激情视频在线观看| 91麻豆精品国产高清在线| 青草国产在线| 国产91精品一区| 91麻豆tv| 91麻豆精品国产综合久久久| a级毛片免费观看网站| 成人免费观看的视频黄页| 精品视频在线看| 欧美电影免费看大全| 国产a网| 精品久久久久久中文字幕一区| 国产不卡精品一区二区三区| 美国一区二区三区| 成人影视在线播放| 久久精品道一区二区三区| 91麻豆精品国产片在线观看| 精品视频在线观看免费| 午夜激情视频在线播放| 国产精品自拍在线| 午夜家庭影院| 国产福利免费观看| 精品国产香蕉伊思人在线又爽又黄| 日韩中文字幕在线播放| 欧美激情一区二区三区视频高清| 黄视频网站在线看| 亚洲精品久久久中文字| 色综合久久天天综合| 欧美电影免费| 国产成人精品综合在线| 国产成人啪精品| 国产91丝袜在线播放0| 成人免费一级纶理片| 午夜激情视频在线观看| 高清一级片| 亚洲精品影院| 毛片电影网| 九九热国产视频| 韩国三级视频网站| 精品毛片视频| 国产麻豆精品视频| 亚飞与亚基在线观看| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 青青久久国产成人免费网站| 一本高清在线| 午夜在线影院| 可以免费看污视频的网站| 亚洲精品永久一区| 欧美激情一区二区三区在线| 日韩一级精品视频在线观看| 在线观看成人网 | 久久国产一区二区| 国产成人啪精品视频免费软件| 亚洲精品久久久中文字| 成人高清免费| 青青久在线视频| 99久久网站| 亚洲精品永久一区| 欧美a级大片| a级黄色毛片免费播放视频| 精品久久久久久中文| 久久99中文字幕| 欧美大片aaaa一级毛片| 超级乱淫伦动漫| 日日夜人人澡人人澡人人看免| 欧美大片一区| 国产91精品一区| 尤物视频网站在线| 国产一区二区精品| 成人高清视频在线观看| 深夜做爰性大片中文| 亚洲天堂免费观看| 午夜激情视频在线播放| 欧美激情中文字幕一区二区| 久久精品免视看国产成人2021| 欧美a级成人淫片免费看| 九九精品在线播放| 四虎影视库| 成人免费网站视频ww| 黄视频网站免费| 麻豆网站在线看| 亚洲www美色| 久草免费在线观看| 尤物视频网站在线| 欧美大片a一级毛片视频| 99久久精品国产片| 91麻豆爱豆果冻天美星空| 精品视频在线看| 国产精品123|