Python學習 :多線程

来源:https://www.cnblogs.com/ArticleYeung/archive/2019/04/05/10657958.html
-Advertisement-
Play Games

多線程 什麼是線程? - 能獨立運行的基本單位——線程(Threads)。 - 線程是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。 - 一條線程指的是進程中一個單一順序的控制流,一個進程中可以併發多個線程,每條線程並行執行不同的任務。 - 就好比生產的工廠,一個車 ...


 多線程

  什麼是線程?

  - 能獨立運行的基本單位——線程(Threads)。

  - 線程是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。

  - 一條線程指的是進程中一個單一順序的控制流,一個進程中可以併發多個線程,每條線程並行執行不同的任務。

  - 就好比生產的工廠,一個車間的工作過程是一個進程,車間中的一條條流水線工作的過程是不同的線程。

  下麵的圖片就是線程與進程之間的關係

 

  註意:進程是資源分配的最小單位,線程是CPU調度的最小單位.

             每一個進程中至少有一個線程。

  線程與進程的區別可以歸納為以下4點:

  1)地址空間和其它資源(如打開文件):進程間的地址空間相互獨立,同一進程的各線程間共用進程的地址空間。某進程內的線程在其它進程不可見

  2)通信:進程間通信IPC,線程間可以直接讀寫進程數據段(如全局變數)來進行通信——需要進程同步和互斥手段的輔助,以保證數據的一致性

  3)調度和切換:線程上下文切換比進程上下文切換要快得多

  4)在多線程操作系統中,進程不是一個可執行的實體

  創建多線程簡例

import time
import threading

def foo(n):
    print('線程%s'%n)
    time.sleep(3)
    print('線程%s結束' % n)

def bar(n):
    print('線程%s' % n)
    time.sleep(2)
    print('線程%s結束' % n)

begin = time.time()
print('------------主線程------------')
# 創建線程對象
t1 = threading.Thread(target = foo,args = (1,))
t2 = threading.Thread(target = bar,args = (2,))
# 通過 os 調度來搶占 cpu資源

t1.start()
t2.start()

# 線程不結束就不會繼續向下進行
t1.join()
t2.join()

end = time.time()
print(end-begin)

  join()方法

  - join()方法會使線程在join處進行阻塞,倘若線程沒完成就不會繼續向下運行

import time
import threading
from time import ctime,sleep

def music(func):
    for i in range(2):
        print ("Begin listening to %s. %s" %(func,ctime()))
        sleep(4)
        print("----------end listening %s----------"%ctime())

def moive(func):
    for i in range(2):
        print ("Begin watching at the %s! %s" %(func,ctime()))
        sleep(5)
        print('----------end watching %s----------'%ctime())

threads = []
t1 = threading.Thread(target=music,args=('晴天',))
threads.append(t1)
t2 = threading.Thread(target=moive,args=('肖申克的救贖',))
threads.append(t2)

if __name__ == '__main__':
    start = time.time()
    for t in threads:
        t.start()
        #t.join() # t 先取的值為 t1 ,t1不結束就不會繼續向下走,此時相當於串列
        #t1.join() # 與 t.join() 效果一致
    t.join() # 在python中不會報錯,此時取值為 t2
    #t2.join()  # 在 t2 運行完成後,才會完成後續代碼
    print ("all over %s" %ctime())
    end = time.time()
    print(end - start)

  守護線程 Daemon

  - 守護線程setDaemon(True),必須在start() 方法調用之前設置,否則將會報錯

  - 如果不設置為守護線程程式會被無限掛起。這個方法基本和join是相反的。

  - 主線程一旦結束,子線程也同時結束

  - 當主線程完成時不需要某個子線程完全運行完就要退出程式,那麼就可以將這個子線程設置為守護線程,

import threading
import time
class MyThread(threading.Thread):
    def __init__(self, num):
        threading.Thread.__init__(self)
        self.num = num

    def run(self):  # 定義每個線程要運行的函數
        print("running on number:%s" % self.num)
        time.sleep(10)

if __name__ == '__main__':
    begin = time.time()
    t1 = MyThread(1)
    t2 = MyThread(2)
    threads = [t1, t2]
    for t in threads:
        t.setDaemon(True)
        t.start()
    print('進程結束!')
    end = time.time()
    print(end-begin)

  隊列 queue

  - queue類的方法

創建一個“隊列”對象
import Queue
q = Queue.Queue(maxsize = 10)
Queue.Queue類即是一個隊列的同步實現。隊列長度可為無限或者有限。可通過Queue的構造函數的可選參數maxsize來設定隊列長度。如果maxsize小於1就表示隊列長度無限。

將一個值放入隊列中
q.put(10)
調用隊列對象的put()方法在隊尾插入一個項目。put()有兩個參數,第一個item為必需的,為插入項目的值;第二個block為可選參數,預設為
1。如果隊列當前為空且block為1,put()方法就使調用線程暫停,直到空出一個數據單元。如果block為0,put方法將引發Full異常。

將一個值從隊列中取出
q.get()
調用隊列對象的get()方法從隊頭刪除並返回一個項目。可選參數為block,預設為True。如果隊列為空且block為True,get()就使調用線程暫停,直至有項目可用。如果隊列為空且block為False,隊列將引發Empty異常。

Python Queue模塊有三種隊列及構造函數:
1、Python Queue模塊的FIFO隊列先進先出。  class queue.Queue(maxsize)
2、LIFO類似於堆,即先進後出。             class queue.LifoQueue(maxsize)
3、還有一種是優先順序隊列級別越低越先出來。   class queue.PriorityQueue(maxsize)

此包中的常用方法(q = Queue.Queue()):
q.qsize() 返回隊列的大小
q.empty() 如果隊列為空,返回True,反之False
q.full() 如果隊列滿了,返回True,反之False
q.full 與 maxsize 大小對應
q.get([block[, timeout]]) 獲取隊列,timeout等待時間
q.get_nowait() 相當q.get(False)
非阻塞 q.put(item) 寫入隊列,timeout等待時間
q.put_nowait(item) 相當q.put(item, False)
q.task_done() 在完成一項工作之後,q.task_done() 函數向任務已經完成的隊列發送一個信號
q.join() 實際上意味著等到隊列為空,再執行別的操作

  隊列的簡例

import threading,queue
from time import sleep
from random import randint
class Production(threading.Thread):
    def run(self):
        while True:
            r = randint(0,100)
            q.put(r)
            print("生產出來%s號包子"%r)
            sleep(1)
class Proces(threading.Thread):
    def run(self):
        while True:
            re = q.get()
            print("吃掉%s號包子"%re)
if __name__=="__main__":
    q = queue.Queue(10)
    threads = [Production(),Production(),Production(),Proces()]
    for t in threads:
        t.start()

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

-Advertisement-
Play Games
更多相關文章
  • 前言 鎖,顧名思義就是鎖住一些資源,當只有我們拿到鑰匙的時候,才能操作鎖住的資源。在我們的Java,資料庫,還有一些分散式的環境中,總是充斥著各種各樣的鎖讓人頭疼,例如“公平鎖”、“自旋鎖”、“讀寫鎖”、“分散式鎖”等等。 其實真實的情況是,鎖並沒有那麼多,很多概念只是從不同的功能特性,設計,以及鎖 ...
  • 一般情況下,在我們做訪問許可權管理的時候,會把用戶的正確登錄後的基本信息保存在Session中,以後用戶每次請求頁面或介面數據的時候,拿到 Session中存儲的用戶基本信息,查看比較他有沒有登錄和能否訪問當前頁面。 Session的原理,也就是在伺服器端生成一個SessionID對應了存儲的用戶數據 ...
  • 定義 提供了一個統一的介面,用來訪問子系統中一群介面 適用場景 詳解 外觀模式,主要理解外觀。通俗一點可以認為這個模式是將子系統封裝到一起,提供給應用的層面就提供一個方法。不直接由應用層直接訪問子系統。 下麵我們看看ibatis的源碼來具體理解外觀模式。 上述代碼其實是完成一個創建MetaObjec ...
  • 簡單工廠模式概述 簡單工廠模式的結構與實現 結構: 實現 1 abstract class Product 2 { 3 public void MethName() 4 { 5 //公共方法的實現 6 } 7 public abstract void MethodDiff(); 8 //聲明抽象業務 ...
  • 定義: 指原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。不需要知道任何創建的細節,不調用構造函數適用場景: 詳解: 接下來我們分下麵幾部分講解: 1.原型模式的核心 其實很簡單,就是實現Cloneable介面,然後重寫clone()方法。上面我們已經說過 ,當你在上面的適用場景中的時 ...
  • 模式的誕生與定義 -Context(模式可適用的前提條件)-Theme或Problem(在特定條件下要解決的目標問題)-Solution(對目標問題求解過程中各種物理關係的記述) 設計模式的分類 Gof設計模式 創建型模式(關註對象的創建過程,對類的實例化過程進行抽象,描述如何將對象的創建和使用分離 ...
  • 概念重覆請求是指一個請求因為某些原因被多次提交,場景簡述如下:1)用戶快速多次點擊按鈕2)Nginx失敗重試機制3)服務框架失敗重試機制4)MQ消息重覆消費5)第三方支付支付成功後,因為異常原因導致的多次非同步回調; 冪等性是指同樣的請求參數,多次請求返回的結果相同。一般是因為重覆請求導致的重覆操作等 ...
  • 經過前兩個模式的學習,是不是對設計模式有了進一步的認識了呢,現在,我們繼續沖鴨。 本章可以稱為“給愛用繼承的人一個全新的設計眼界”。這裡我們即將再度探討典型的繼承濫用問題,我們將學到如何使用對象組合的方式,做到在運行時裝飾類。為什麼呢?一旦熟悉了裝飾的技巧,你將能夠在不修改任何底層代碼的情況下,給對 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...