黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

python進(jìn)程、線程

系統(tǒng) 2577 0

為什么編程的時候要使用進(jìn)程、線程、協(xié)程?使用它們是為了進(jìn)行多并發(fā)編程。那么為什么要進(jìn)行多并發(fā)編程?因?yàn)槎嗖l(fā)編程可以減少程序運(yùn)行的時間,讓用戶獲得更好的體驗(yàn)。

1.進(jìn)程

概念:操作系統(tǒng)執(zhí)行程序分配存儲空間的最小單位。一個CPU只能同時處理一個進(jìn)程。python實(shí)現(xiàn)多進(jìn)程,使用multiprocessing模塊的Process類來創(chuàng)建進(jìn)程。具體代碼如下:

            
              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,花費(fèi)%s秒"%(filename,task))

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

if __name__  == "__main__":
    main()
            
          

輸出結(jié)果如下:

python進(jìn)程、線程_第1張圖片

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

2.線程

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

            
              from threading import Thread
from random import randint
import time

#創(chuàng)建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,花費(fèi)%s秒"%(self._filename,task))

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

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

if __name__ == "__main__":
    main()
            
          

輸出結(jié)果如下:

python進(jìn)程、線程_第2張圖片

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

            
              from threading import Thread
from random import randint
import time

class Repertory(object):
    "創(chuàng)建倉庫類"
    def __init__(self):
        #初始化倉庫數(shù)量
        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):
        #返回倉庫庫存數(shù)量
        return self._initialize_number


class AddNumberThread(Thread):

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

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

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


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

if __name__ == "__main__":
    main()
            
          

輸出結(jié)果如下:

運(yùn)行結(jié)果與我們想象中的完全不一樣,因?yàn)榇蟛糠志€程啟動的時候,self._initialize_number都等于100,要解決這個問題,就需要用到線程鎖。在代碼中加入鎖,修改后的代碼如下:

            
              from threading import Thread, Lock
import time

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

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


class AddNumberThread(Thread):

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

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

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


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

if __name__ == "__main__":
    main()
            
          

輸入結(jié)果如下:


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

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

【本文對您有幫助就好】

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

發(fā)表我的評論
最新評論 總共0條評論