最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python基礎(chǔ)教程之多線程編程詳解

 更新時(shí)間:2023年06月15日 09:20:04   作者:陸理手記  
Python支持多線程編程和多進(jìn)程編程,在本教程中,我們將學(xué)習(xí)有關(guān)Python多線程編程的基礎(chǔ)知識、線程同步、線程池以及如何使用多進(jìn)程,需要的朋友可以參考下

進(jìn)程(process)指的是正在運(yùn)行的程序的實(shí)例,當(dāng)我們執(zhí)行某個(gè)程序時(shí),進(jìn)程就被操作系統(tǒng)創(chuàng)建了。而線程(thread)則包含于進(jìn)程之中,是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單元,多個(gè)線程可以同處一個(gè)進(jìn)程中,且同時(shí)處理不同的任務(wù)。一條進(jìn)程中可以并發(fā)多個(gè)線程,而同一條線程將共享該進(jìn)程中的全部系統(tǒng)資源。

每個(gè)進(jìn)程都有自己獨(dú)立的地址空間、內(nèi)存和數(shù)據(jù)棧,因此進(jìn)程之間通訊不方便,所以需使用用進(jìn)程間通訊(InterProcess Communication, IPC)。而同一個(gè)進(jìn)程中的線程共享資源,因此線程間通訊非常方便,只需注意數(shù)據(jù)同步與互斥的問題。

1. 多線程基礎(chǔ)

線程是進(jìn)程內(nèi)的執(zhí)行單元,每個(gè)進(jìn)程都至少有一個(gè)線程。Python標(biāo)準(zhǔn)庫提供了thread模塊和threading模塊來支持線程編程。在Python3中,thread模塊已經(jīng)改名為_thread,并在_thread基礎(chǔ)上開發(fā)了更為強(qiáng)大的threading模塊,因此我們可以使用threading.Thread類創(chuàng)建線程對象,并通過start()方法啟動(dòng)線程。

import threading
def worker():
    print("I am a thread.")
t = threading.Thread(target=worker)
t.start()

在上面的代碼中,我們創(chuàng)建了一個(gè)名為worker的函數(shù),它是線程的工作內(nèi)容。我們使用threading.Thread類創(chuàng)建了一個(gè)線程對象t,并將worker作為參數(shù)傳遞給了Thread構(gòu)造函數(shù)。然后,我們調(diào)用t.start()方法來啟動(dòng)線程。當(dāng)我們運(yùn)行這段代碼時(shí),會(huì)看到以下輸出:

I am a thread.

另外,我們也可以通過繼承Thread類并重寫run方法來實(shí)現(xiàn)線程的創(chuàng)建.

import threading
class MyThread(threading.Thread):
	def __init__(self, n):
		self.n = n
		super().__init__() # 調(diào)用父類函數(shù)初始化線程
	def run(self):
		print('線程:', self.n)
for i in range(1,3):
	t = MyThread(i)
	t.start()

果應(yīng)該輸出打印出:

線程1
線程2

2. 多線程同步

當(dāng)多個(gè)線程同時(shí)訪問共享資源時(shí),可能會(huì)發(fā)生競態(tài)條件。為避免這種情況,我們需要使用線程同步機(jī)制。Python提供了鎖(Lock)、信號量(Semaphore)、事件(Event)等機(jī)制來實(shí)現(xiàn)線程同步。

下面是一個(gè)使用鎖來確保線程同步的示例:

import threading
lock = threading.Lock()
count = 0
def worker():
    global count
    lock.acquire()
    try:
        count += 1
    finally:
        lock.release()
threads = []
for i in range(10):
    t = threading.Thread(target=worker)
    threads.append(t)
for t in threads:
    t.start()
for t in threads:
    t.join()
print(count)

在上面的代碼中,我們定義了一個(gè)全局變量count和一個(gè)鎖對象lock。worker函數(shù)是每個(gè)線程的工作內(nèi)容,它通過lock來確保count的修改是原子性的。我們創(chuàng)建了10個(gè)線程并啟動(dòng)它們,等待所有線程執(zhí)行完畢后輸出count的值。當(dāng)我們運(yùn)行這段代碼時(shí),會(huì)看到以下輸出:

10

如果把鎖去掉后,count的值會(huì)是幾呢?動(dòng)手試試吧!會(huì)有意向不到的結(jié)果哦~

3. 線程池

線程池可以用來提高代碼的性能,在需要大量線程處理任務(wù)時(shí),可以使用線程池來減少線程的創(chuàng)建和銷毀次數(shù),提高線程的復(fù)用率。

Python標(biāo)準(zhǔn)庫提供了concurrent.futures模塊來支持線程池編程。我們可以使用ThreadPoolExecutor類來創(chuàng)建和管理線程池。

下面是一個(gè)使用線程池來處理任務(wù)的示例:

from concurrent.futures import ThreadPoolExecutor
def worker(num):
    return num * num
executor = ThreadPoolExecutor(max_workers=4)
results = []
for i in range(10):
    result = executor.submit(worker, i)
    results.append(result)
for result in results:
    print(result.result())

在上面的代碼中,我們定義了一個(gè)worker函數(shù)用來處理任務(wù)。我們創(chuàng)建了一個(gè)ThreadPoolExecutor對象executor,并將最大工作線程數(shù)設(shè)置為4。然后,我們使用submit方法提交10個(gè)任務(wù)給executor,并將結(jié)果保存在results列表中。最后,我們遍歷results列表并輸出每個(gè)任務(wù)的結(jié)果。

看到這些個(gè)熟悉的單詞...恍惚間有種寫java代碼的感覺。

4. 多進(jìn)程編程

進(jìn)程是計(jì)算機(jī)中程序執(zhí)行的基本單位,而線程則是進(jìn)程中執(zhí)行代碼的單位。多進(jìn)程編程就是利用多個(gè)獨(dú)立運(yùn)行的進(jìn)程來完成任務(wù)。相比單進(jìn)程,多進(jìn)程有以下優(yōu)點(diǎn):

  • 提高了程序的并發(fā)性能。
  • 可以更好地利用多核CPU。
  • 能夠處理更大的數(shù)據(jù)集。

在進(jìn)行多進(jìn)程編程時(shí),需要注意進(jìn)程之間的通信和同步問題。

5. Python實(shí)現(xiàn)多進(jìn)程編程

Python標(biāo)準(zhǔn)庫中的multiprocessing模塊提供了實(shí)現(xiàn)多進(jìn)程編程的工具。其中常用的方法包括:

  • Process:創(chuàng)建一個(gè)新進(jìn)程。
  • Pool:創(chuàng)建一組進(jìn)程池。
  • Queue:進(jìn)程之間的消息隊(duì)列。

下面是一個(gè)簡單的示例,展示如何使用multiprocessing模塊創(chuàng)建子進(jìn)程:

import multiprocessing
def worker():
    """子進(jìn)程要執(zhí)行的任務(wù)"""
    print('子進(jìn)程正在運(yùn)行')
if __name__ == '__main__':
    p = multiprocessing.Process(target=worker)
    p.start()
    print('主進(jìn)程已經(jīng)結(jié)束')

在這個(gè)例子中,我們創(chuàng)建一個(gè)新的進(jìn)程,并將其target屬性指向worker函數(shù)。然后使用start方法啟動(dòng)該進(jìn)程。注意到在Windows系統(tǒng)中,需要將啟動(dòng)進(jìn)程的代碼放在if __name__ == '__main__':語句內(nèi),以避免出現(xiàn)一些問題。

5.1 Python進(jìn)程池

import multiprocessing
def worker(num):
    """子進(jìn)程要執(zhí)行的任務(wù)"""
    print(f'子進(jìn)程{num}正在運(yùn)行')
if __name__ == '__main__':
    with multiprocessing.Pool(processes=4) as pool:
        results = pool.map(worker, range(4))
        print(results)

在這個(gè)例子中,我們使用了進(jìn)程池來管理多個(gè)子進(jìn)程。首先創(chuàng)建一個(gè)Pool對象,其中processes參數(shù)指定了進(jìn)程池的大小。然后使用map方法提交任務(wù),該方法會(huì)自動(dòng)分配任務(wù)給空閑的子進(jìn)程并返回結(jié)果。最后打印輸出結(jié)果。

5.2 在進(jìn)程之間進(jìn)行通信

import multiprocessing
def writer(q):
    """寫入數(shù)據(jù)"""
    for i in range(10):
        q.put(i)
def reader(q):
    """讀取數(shù)據(jù)"""
    while True:
        item = q.get()
        if item is None:
            break
        print(item)
if __name__ == '__main__':
    q = multiprocessing.Queue()
    # 啟動(dòng)子進(jìn)程
    p1 = multiprocessing.Process(target=writer, args=(q,))
    p2 = multiprocessing.Process(target=reader, args=(q,))
    p1.start()
    p2.start()
    # 等待子進(jìn)程結(jié)束
    p1.join()
    q.put(None)
    p2.join()

在這個(gè)例子中,我們創(chuàng)建了一個(gè)消息隊(duì)列,并通過Queue對象將其傳遞給兩個(gè)子進(jìn)程。一個(gè)子進(jìn)程負(fù)責(zé)將數(shù)據(jù)寫入隊(duì)列中,而另一個(gè)子進(jìn)程則從隊(duì)列中讀取數(shù)據(jù)并輸出到屏幕上。注意到在程序末尾我們向隊(duì)列中添加了None元素,以便通知讀取數(shù)據(jù)的子進(jìn)程結(jié)束循環(huán)。

6.多進(jìn)程計(jì)算圓周率

下面是使用Python多進(jìn)程和蒙特卡羅(Monte Carlo)方法估計(jì)圓周率的示例代碼:

import random
from multiprocessing import Pool
def estimate_pi(n):
    num_points_inside_circle = 0
    for _ in range(n):
        x = random.uniform(-1, 1)
        y = random.uniform(-1, 1)
        if x**2 + y**2 <= 1:
            num_points_inside_circle += 1
    return 4 * num_points_inside_circle / n
if __name__ == '__main__':
    num_processes = 4
    num_samples = int(1e8)
    with Pool(num_processes) as p:
        results = p.map(estimate_pi, [int(num_samples/num_processes)] * num_processes)
    print(sum(results)/num_processes)

該代碼使用random模塊中的uniform函數(shù)生成在[−1,1][-1, 1][−1,1]范圍內(nèi)均勻分布的隨機(jī)數(shù),并統(tǒng)計(jì)落入以原點(diǎn)為圓心,半徑為1的圓中的點(diǎn)數(shù)。最后,將所有子進(jìn)程的結(jié)果相加并除以進(jìn)程數(shù)以得到圓周率的估計(jì)值。我算出的結(jié)果是3.1416664800000005, 你們呢?

其中,Pool(num_processes) 創(chuàng)建一個(gè)具有num_processes個(gè)進(jìn)程的進(jìn)程池,p.map(estimate_pi, [int(num_samples/num_processes)] * num_processes) 在每個(gè)進(jìn)程上調(diào)用estimate_pi函數(shù),并將輸入?yún)?shù)設(shè)為所需的樣本數(shù)量的四分之一,然后返回其結(jié)果。

7.總結(jié)

在Python多線程與進(jìn)程編程中,我們不僅要理解和掌握的關(guān)于threading 模塊和multiprocessing模塊如何使用,更要掌握的是線程和進(jìn)程之間的區(qū)別和聯(lián)系以及線程通信、進(jìn)程通信的方式。

Python提供了豐富的多線程和多進(jìn)程編程工具,使我們能夠更有效地利用計(jì)算機(jī)的多核心處理能力。線程同步和線程池等同步原語可以幫助我們避免競爭條件,并提高程序性能。使用好多線程和多進(jìn)程,可以使Python編程變得更加高效和靈活。Python爬蟲應(yīng)用中,經(jīng)常會(huì)大量使用線程和進(jìn)程來提升抓取效率哦

以上就是Python基礎(chǔ)教程之多線程編程詳解的詳細(xì)內(nèi)容,更多關(guān)于Python多線程編程的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python實(shí)現(xiàn)的求解最小公倍數(shù)算法示例

    Python實(shí)現(xiàn)的求解最小公倍數(shù)算法示例

    這篇文章主要介紹了Python實(shí)現(xiàn)的求解最小公倍數(shù)算法,涉及Python數(shù)值運(yùn)算、判斷等相關(guān)操作技巧,需要的朋友可以參考下
    2018-05-05
  • 如何通過python的fabric包完成代碼上傳部署

    如何通過python的fabric包完成代碼上傳部署

    這篇文章主要介紹了如何通過python的fabric包完成代碼上傳部署,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • python os模塊常用的29種方法使用詳解

    python os模塊常用的29種方法使用詳解

    這篇文章主要介紹了python os模塊常用的29種方法使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Python結(jié)合MySQL數(shù)據(jù)庫編寫簡單信息管理系統(tǒng)完整實(shí)例

    Python結(jié)合MySQL數(shù)據(jù)庫編寫簡單信息管理系統(tǒng)完整實(shí)例

    最近Python課堂上布置了綜合實(shí)訓(xùn),實(shí)驗(yàn)?zāi)繕?biāo)是設(shè)計(jì)一個(gè)信息管理系統(tǒng),下面這篇文章主要給大家介紹了關(guān)于Python結(jié)合MySQL數(shù)據(jù)庫編寫簡單信息管理系統(tǒng)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • Python圖像處理必備技巧分享

    Python圖像處理必備技巧分享

    本文系統(tǒng)梳理了Python圖像處理的15項(xiàng)核心技能,涵蓋圖像讀取、顏色轉(zhuǎn)換、濾波、邊緣檢測、形態(tài)學(xué)操作、特征提取、分割、變換等關(guān)鍵技術(shù),強(qiáng)調(diào)這些基礎(chǔ)技能的組合應(yīng)用可實(shí)現(xiàn)復(fù)雜圖像處理任務(wù),需要的朋友可以參考下
    2025-05-05
  • Python找出list中最常出現(xiàn)元素的方法

    Python找出list中最常出現(xiàn)元素的方法

    這篇文章主要介紹了Python找出list中最常出現(xiàn)元素的方法,給出了三種常用的方法供大家對比參考,需要的朋友可以參考下
    2016-06-06
  • Python邏輯運(yùn)算符詳解與實(shí)際應(yīng)用指南

    Python邏輯運(yùn)算符詳解與實(shí)際應(yīng)用指南

    這篇文章主要介紹了Python邏輯運(yùn)算符詳解與實(shí)際應(yīng)用指南的相關(guān)資料,包括真值表、短路求值特性、運(yùn)算符優(yōu)先級及非布爾類型的處理,還提供了實(shí)際應(yīng)用案例和注意事項(xiàng),文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-04-04
  • 使用國內(nèi)鏡像源優(yōu)化pip install下載的方法步驟

    使用國內(nèi)鏡像源優(yōu)化pip install下載的方法步驟

    在Python開發(fā)中,pip 是一個(gè)不可或缺的工具,用于安裝和管理Python包,然而,由于默認(rèn)的PyPI服務(wù)器位于國外,國內(nèi)用戶在安裝依賴時(shí)可能會(huì)遇到下載速度慢、連接不穩(wěn)定等問題,所以本文將詳細(xì)介紹如何使用國內(nèi)鏡像源來加速pip install -r requirements.txt的過程
    2025-03-03
  • Python中的生成器

    Python中的生成器

    這篇文章主要介紹了Python中的生成器
    2021-12-12
  • python數(shù)組循環(huán)處理方法

    python數(shù)組循環(huán)處理方法

    今天小編就為大家分享一篇python數(shù)組循環(huán)處理方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08

最新評論

合肥市| 陇川县| 嘉义市| 海淀区| 镇宁| 礼泉县| 乳山市| 长子县| 盐边县| 息烽县| 台安县| 黎城县| 山阴县| 南投县| 汕尾市| 富宁县| 织金县| 新化县| 广丰县| 奉化市| 太谷县| 康保县| 临夏县| 通化市| 淮南市| 河北区| 平顺县| 宜宾市| 政和县| 手游| 清原| 西充县| 利辛县| 柯坪县| 沙坪坝区| 南丹县| 湘乡市| 乌兰察布市| 台北市| 溆浦县| 乳源|