Python學習之路-隨筆03 多線程/進程和協程(上篇)

来源:https://www.cnblogs.com/slose-notes/archive/2018/09/19/9672312.html
-Advertisement-
Play Games

最近東西積攢了太多,感覺再不寫進來就要炸了。 1.多線程 1.11 關於多線程的包 相關的python包有幾個,比如thread包,到py3改成_thread,而thread有一些問題使得不是很好用。通用的包叫threading。最近都是在用這個。 1.12 threading的使用和常用屬性 需要 ...


  

 最近東西積攢了太多,感覺再不寫進來就要炸了。

1.多線程

1.11 關於多線程的包

相關的python包有幾個,比如thread包,到py3改成_thread,而thread有一些問題使得不是很好用。通用的包叫threading。最近都是在用這個。

1.12 threading的使用和常用屬性

需要註意的點有生成實例比如t = threading.Thread(target=xxx, args=(xx,)),裡面有兩個參數,第一個是目標函數,第二個是相關的參數,註意類型。

然後就是start啟動,join等待多線程實行完成這兩個方法。

#偽代碼
t1 = threading.Thread(target=fun1, args=("函數參數 1",))
t1.start()

t2 = threading.Thread(target=fun2, args=("函數參數1", "函數參數2"))
t2.start()

#等待線程
t1.join()
t2.join()

繼承threading.Thread使用,需要重寫run函數。

class MyThread(threading.Thread):
  def __init__(self, arg):
    super(MyThread, self).__init__()
    self.arg = arg

  def run(self):
    time.sleep(2)

其他常用屬性和方法有:

threading.currentThread:返回當前線程變數

threading.enumerate:返回一個包含正在運行的線程的list,正在運行的線程指的是線程啟動後,結束前的狀態

threading.activeCount: 返回正在運行的線程數量,效果跟 len(threading.enumerate)相同

threading.timer: 定時器,利用多線程在指定時間後啟動一個功能

thr.setName: 給線程設置名字

thr.getName: 得到線程的名字

守護線程:daemon:即如果將子線程設置成守護線程,則子線程會在主線程結束的時候自動退出,一般認為,守護線程不中要或者不允許離開主線程獨立運行

而守護線程能否有效果跟環境相關

t1 = threading.Thread(target=fun, args=() )
# 社會守護線程的方法,必須在start之前設置,否則無效
t1.setDaemon(True)
#t1.daemon = True
t1.start()

 

1.13 線程相關的問題

因為線程之間有共用狀態(資源),會有一些諸如死鎖或者同步的問題。解決方法也是大同小異,這些python里都給出了

相應的工具。比如自己設置一個鎖/信號燈。用semphore變數,還有可重入鎖解鎖遞歸的時候申請鎖的問題等等。

線程安全不安全變數list,set,dict,安全變數queue等。

1.14 線程替代方案

替代無非是用進程或者魔改的線程包,諸如subprocess使用進程,multiprocessing用threading派生出來的,使用子進程,可以使用多核或多CPU

還有一個current.future待會兒寫

2.多進程

使用的就是上面提到的線程替代方案multiprocessing,方法和threading差不多,multiprocessing.Process(target=xxx, args=(xx,)),然後同樣也可以繼承後使用,實現方式類似多線程

還有一個就是pid和ppid,即進程ID和父進程ID,還有其他常見的內容比如子進程和父進程共用資源啊,而子線程有自己獨立的棧空間啊之類的就不詳細描述了

還有其他的諸如生產者-消費者模型,讀者-寫者模型等等。和上面的一樣,也不贅述了,操作系統書里都有,寫在這沒什麼意義。

3.協程

首先來寫一下協程的定義:協程是為非搶占式多任務產生子程式的電腦程式組件, 協程允許不同入口點在不同位置暫停或開始執行程式。 

 在這之前先寫兩個

3.11 迭代器

有兩個概念,一是可迭代對象Iterable,二是迭代器Iterator

Iterable可以用於for迴圈,二Iterator不僅可以用於for迴圈還能被next函數調用,可以用isinstance函數判斷,比如list是可迭代的。

from collections import Iterable

l = [1,2,3,4]

isinstance(l, Iterable)

out:True

兩者之間還可以通過iter函數轉換

from collections import Iterator

isinstance(iter('abc'), Iterator)

out:True

3.12 生成器

比如最常見的生成器有L = [x * x for x in range(10)],g = (x * x for x in range(10))這些生成列表,元組的方法

本質是一個函數/方法,每次調用next的時候計算下一個值,最後會拋出StopIteration異常。

函數中包含yield,則叫generator

next調用,遇到yield返回

# 在函數odd中,yield負責返回
def odd():
    print("Step 1")
    yield 1
    print("Step 2")
    yield 2
    print("Step 3")
    yield 3
 
# odd() 是調用生成器
g = odd()
one = next(g)
print(one)

two = next(g)
print(two)

three = next(g)
print(three)

out:Step 1

  1

  Step 2

  2

  Step 3

  3

3.13 協程

是的,協程和生成器很像,使用yield和send。目的是合理調用各種系統資源和進行協同工作。協程之間切換耗費也很低

協程有四個狀態:

GEN_CREATED:等待開始執行

GEN_RUNNING:解釋器正在執行

GEN_SUSPENED:在yield表達式處暫停

GEN_CLOSED:執行結束

def simple_coroutine(a):
    print('-> start') 

    b = yield a # 把A丟出來給aa
    print('-> recived', a, b)

    c = yield a + b
    print('-> recived', a, b, c)

# runc
sc = simple_coroutine(5)

aa = next(sc) # 預激,準備好執行協程,程式走到yield停下
print(aa) 
bb = sc.send(6) # 5 ,6  把參數6發給b
print(bb)
cc = sc.send(7) # 5, 6, 7
print(cc)#執行不到,拋出StopIteration異常

out:

-> start

5

-> recived 5 6

11

-> recived 5 6 7

之前說過,最後會拋出一個StopIteration異常,未處理的異常會向上冒泡,傳給next函數或send函數的調用方。終止協程可以發送某個哨符,讓協程退出,比如內置的None和Ellipsis等常量

還有兩個和異常相關的方法generator.throw(Exctpiton)和generator.close()

大概作用就是前一個會在暫停的yield出拋出指定的異常。如果生成器處理了該異常,則代碼會執行到下一個yield

而產出的值(value,異常的一個屬性)會成為調用 generator.throw方法得到的返回值。沒處理則往上冒泡。

第二個的作用是致使生成器在暫停的 yield 表達式處拋出 GeneratorExit 異常。如果生成器沒有處理這個異常,或者拋出了 StopIteration 異常(通常是指運行到結尾),調用方不會報錯。

如果收到 GeneratorExit 異常,生成器一定不能產出值,否則解釋器會拋出RuntimeError 異常。生成器拋出的其他異常會向上冒泡,傳給調用方。

以下是找到的一段事例代碼

class DemoException(Exception):
    """
    custom exception
    """
    pass

def handle_exception():
    print('-> start')

    while True:
        try:
            x = yield
        except DemoException:
            print('-> run demo exception')
        else:
            print('-> recived x:', x)

    raise RuntimeError('this line should never run')

he = handle_exception()
next(he)
he.send(10) # recived x: 10
he.send(20) # recived x: 20

he.throw(DemoException) # run demo exception

he.send(40) # recived x: 40
he.close()
View Code

yield from

相對於yield,yield from就相當於在調用方和生成器之間多了一層“通道”類似的代理。(又或者說在主線程和協程之間)

使用的渠道:比如委派生成器。

1,定義一個生成器(含yield)可以一次次的接收調用方傳來的值(通過yield)和return回去處理後的值

2,定義個委派生成器,只需要yield from 生成器即可使用並接收值

3,調用委派生成器使用

未完待續


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 關鍵字:架構設計 軟體質量保證 資料庫完整性 1、資料庫完整性討論 有許多同學認為開發階段沒必要建立外鍵約束,更不用建立檢查約束,因為會影響單表數據寫入做測試。 這個想法是非常錯誤的,不規範的,不專業的。 首先影不影響測試是無稽之談,說明這類同學開發時不會寫單元測試,通過野路子來測試,質量不保。 然 ...
  • 本地部署時代 在軟體還是“本地部署(on-premise)”的時候,SaaS的版圖被大型玩家把持著,幾乎所有的垂直領域(營銷、支持、銷售、人力)都被微軟、SAP等大公司的解決方案占據。那時候的用戶並沒有什麼“軟體棧”可供選擇。 第一代SaaS冠軍 隨著互聯網的不斷普及,SaaS模式開始發揮作用。第一 ...
  • sleep(休眠) 和 wait(等待) 方法是 Java 多線程中常用的兩個方法,它們有什麼區別及一些該註意的地方有哪些呢?下麵給大家一一分解。 區別1:使用限制 使用 sleep 方法可以讓讓當前線程休眠,時間一到當前線程繼續往下執行,在任何地方都能使用,但需要捕獲 InterruptedExc ...
  • 軟體構造工具包括程式編輯器,編譯器,代碼生成器,解釋器和調試器 ...
  • lambda 表達式 剖析 大前提:捕獲列表裡變數的確定時機。 捕獲列表和參數列表有區別,捕獲列表裡的變數,是在捕獲的時間點就確定了,而不是在lambda調用時確定,參數列表是在調用時才確定。所以當捕獲了一個int i,i=12,然後在lambda後面的代碼又改變i為22,但是當調用lambda的時 ...
  • 原文出自: "http://cmsblogs.com" 在 方法中做了兩件事情,一是調用 獲取 XML 的驗證模式,二是調用 獲取 Document 對象。上篇博客已經分析了獲取 XML 驗證模式( "【死磕Spring】 IOC 之 獲取驗證模型" ),這篇我們分析獲取 Document 對象。 ...
  • 本文首發於我的個人博客: "尾尾部落" 本文是我刷了幾十篇一線互聯網校招java後端開發崗位的面經後總結的多線程相關題目,雖然有點小長,但是面試前看一看,相信能幫你輕鬆啃下多線程這塊大骨頭。 什麼是進程,什麼是線程?為什麼需要多線程編程? 進程間的通信方式、線程間的通信方式 實現多線程的三種方法 三 ...
  • 轉載自 https://blog.csdn.net/program_developer/article/details/79677557 目錄: Anaconda是什麼? 如何安裝? 如何管理包? 如何管理環境 1.Anaconda是什麼? 簡單來說,Anaconda是Python的包管理器和環境管 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...