日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

python進程、線程

系統 2336 0

為什么編程的時候要使用進程、線程、協程?使用它們是為了進行多并發編程。那么為什么要進行多并發編程?因為多并發編程可以減少程序運行的時間,讓用戶獲得更好的體驗。

1.進程

概念:操作系統執行程序分配存儲空間的最小單位。一個CPU只能同時處理一個進程。python實現多進程,使用multiprocessing模塊的Process類來創建進程。具體代碼如下:

            
              from multiprocessing import Process
from os import getpid
import time
from random import randint

def download(filename):
    """
    定義一個下載文件的方法
    :param filename:要下載的文件名
    :return:
    """
    task = randint(8, 15)
    time.sleep(task)
    print("下載文件:%s,花費%s秒"%(filename,task))

def main():
    #記錄開始下載時間
    start = time.time()
    #創建一個進程,target為進程要執行的方法,args是一個元組,為調用該方法要傳入的參數。
    p1 = Process(target=download,args=("python自動化測試.pdf",))
    #啟動進程
    p1.start()
    p2 = Process(target=download,args=("測試技巧.pdf",))
    p2.start()
    #執行進程并等待進程執行結束
    p1.join()
    p2.join()
    #記錄下載完成時間
    end = time.time()
    #輸出下載總耗時
    print("下載總耗時%.2f秒"%(end-start))

if __name__  == "__main__":
    main()
            
          

輸出結果如下:

python進程、線程_第1張圖片

使用多進程的編程的好處是可以大大提高代碼的執行效率,但是多進程存在一個問題,進程之前的通信比較復雜,實現起來會占用較大的資源,此時我們引入線程的來解決這個問題。

2.線程

一個進程可以包含多個線程,同一進程中的每個線程的信息是可以進行共享的。python使用threading模塊的Thread類來創建新的線程。python的類是可以繼承的,我們創建類時可以繼承Thread類。具體代碼如下:

            
              from threading import Thread
from random import randint
import time

#創建Download類,繼承Thread類
class Download(Thread):

    def __init__(self, filename):
        super().__init__()
        self._filename = filename

    def run(self):
        task = randint(8, 13)
        time.sleep(task)
        print("下載文件:%s,花費%s秒"%(self._filename,task))

    def close(self):
        print("3sdf%s"%self._filename)

def main():
    start = time.time()
    t1 = Download("python自動化測試.pdf")
    #執行t1.start時,會運行run方法
    t1.start()
    t2 = Download("測試技巧.pdf")
    t2.start()
    t1.join()
    t2.join()
    end = time.time()
    print("下載完成,共耗時%.2f"%(end-start))

if __name__ == "__main__":
    main()
            
          

輸出結果如下:

python進程、線程_第2張圖片

在進行出入庫操作時,多線程并發時,會導致數據丟失問題。我們寫一段代碼,庫存值為100,啟動50個線程同時進行入庫操作,所有線程入庫結束后。理論上最終的庫存值為150。具體代碼如下:

            
              from threading import Thread
from random import randint
import time

class Repertory(object):
    "創建倉庫類"
    def __init__(self):
        #初始化倉庫數量
        self._initialize_number = 100

    def add_number(self,number):
        #入庫操作
        new_number = number+self._initialize_number
        #模擬入庫時間
        time.sleep(0.01)
        #更新倉庫庫存
        self._initialize_number = new_number
    @property
    def number(self):
        #返回倉庫庫存數量
        return self._initialize_number


class AddNumberThread(Thread):

    def __init__(self, repertory, number):
        """

        :param repertory: 倉庫對象
        :param number: 新增庫存數量
        """
        super().__init__()
        self._repertory = repertory
        self._number = number

    def run(self):
        self._repertory.add_number(number=self._number)


def main():
    repertory = Repertory()
    threads = []
    #創建50個線程進行入庫操作
    for _ in range(50):
        t = AddNumberThread(repertory=repertory,number=1)
        threads.append(t)
        t.start()
    #等待所有線程入庫結束
    for thread in threads:
        thread.join()
    #打印最終的庫存數
    print("倉庫庫存數%s"%repertory.number)

if __name__ == "__main__":
    main()
            
          

輸出結果如下:

運行結果與我們想象中的完全不一樣,因為大部分線程啟動的時候,self._initialize_number都等于100,要解決這個問題,就需要用到線程鎖。在代碼中加入鎖,修改后的代碼如下:

            
              from threading import Thread, Lock
import time

class Repertory(object):
    "創建倉庫類"
    def __init__(self):
        #初始化倉庫數量
        self._initialize_number = 100
        #定義鎖
        self._lock = Lock()

    def add_number(self,number):
        #拿到鎖才能執行下面代碼
        self._lock.acquire()
        try:
            #入庫操作
            new_number = number+self._initialize_number
            #模擬入庫時間
            time.sleep(0.01)
            #更新倉庫庫存
            self._initialize_number = new_number
        finally:
            #代碼執行完成后,釋放鎖
            self._lock.release()
    @property
    def number(self):
        #返回倉庫庫存數量
        return self._initialize_number


class AddNumberThread(Thread):

    def __init__(self, repertory, number):
        """

        :param repertory: 倉庫對象
        :param number: 新增庫存數量
        """
        super().__init__()
        self._repertory = repertory
        self._number = number

    def run(self):
        self._repertory.add_number(number=self._number)


def main():
    repertory = Repertory()
    threads = []
    #創建50個線程進行入庫操作
    for _ in range(50):
        t = AddNumberThread(repertory=repertory,number=1)
        threads.append(t)
        t.start()
    #等待所有線程入庫結束
    for thread in threads:
        thread.join()
    #打印最終的庫存數
    print("倉庫庫存數%s"%repertory.number)

if __name__ == "__main__":
    main()
            
          

輸入結果如下:


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 南投市| 耿马| 包头市| 大悟县| 奉化市| 修水县| 瑞金市| 丰台区| 香格里拉县| 海伦市| 武平县| 东乡族自治县| 石棉县| 罗定市| 岳西县| 乌鲁木齐县| 陕西省| 永春县| 民勤县| 东至县| 和平县| 平利县| 格尔木市| 海安县| 扎鲁特旗| 三明市| 杭锦后旗| 泌阳县| 绥化市| 永春县| 木里| 江华| 县级市| 东城区| 达州市| 乐平市| 祁连县| 侯马市| 黎城县| 钟山县| 府谷县|