• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • 并發編程理論篇

    一、必備知識回顧
    計算機又叫電腦,即通電的大腦,發明計算機是為了讓他通電之后能夠像人一樣去工作,并且它比人的工作效率更高,因為可以24小時不間斷

    計算機五大組成部分

    • 控制器
    • 運算器
    • 存儲器
    • 輸入設備
    • 輸出設備
      在這里插入圖片描述

    計算機的核心真正干活的是CPU(控制器+運算器=中央處理器)

    程序要想被計算機運行,它的代碼必須要先由硬盤讀到內存,之后cpu取指再執行
    在這里插入圖片描述
    在這里插入圖片描述
    并發

    • 看起來像同時運行的就可以稱之為并發

    并行

    • 真正意義上的同時執行

    ps:

    • 并行肯定算并發
    • 單核的計算機肯定不能實現并行,但是可以實現并發!!!

    補充:我們直接假設單核就是一個核,干活的就一個人,不要考慮cpu里面的內核數

    多道技術圖解

    • 節省多個程序運行的總耗時
      在這里插入圖片描述

    多道技術重點知識

    空間上的復用與時間上的復用

    • 空間上的復用
      多個程序公用一套計算機硬件
    • 時間上的復用
      例子:洗衣服30s,做飯50s,燒水30s
      單道需要110s,多道只需要任務做長的那一個 切換節省時間
      例子:邊吃飯邊玩游戲 保存狀態

    切換+保存狀態

    切換(CPU)分為兩種情況

    • 1.當一個程序遇到IO操作的時候,操作系統會剝奪該程序的CPU執行權限 作用:提高了CPU的利用率 并且也不影響程序的執行效率
    • 2.當一個程序長時間占用CPU的時候,操作吸引也會剝奪該程序的CPU執行權限 弊端:降低了程序的執行效率(原本時間+切換時間)

    程序與進程的區別

    • 程序就是一堆躺在硬盤上的代碼,是“死”的
    • 進程則表示程序正在執行的過程,是“活”的

    進程調度

    先來先服務調度算法

    • 對長作業有利,對短作業無益

    短作業優先調度算法

    • 對短作業有利,多長作業無益

    時間片輪轉法+多級反饋隊列
    在這里插入圖片描述
    進程運行的三狀態圖
    ![在這里插入圖片描述](https://img-blog.csdnimg.cn/20200422201232577.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dnMTQ3NDc0MjE0MTc=,size_16,color_FFFFFF,t_70

    二 同步和異步

    描述的是任務的提交方式

    • 同步:任務提交之后,原地等待任務的返回結果,等待的過程中不做任何事(干等) 程序層面上表現出來的感覺就是卡住了
    • 異步:任務提交之后,不原地等待任務的返回結果,直接去做其他事情
      我提交的任務結果如何獲取?任務的返回結果會有一個異步回調機制自動處理

    三 阻塞非阻塞

    描述的程序的運行狀態

    • 阻塞:阻塞態
    • 非阻塞:就緒態、運行態

    理想狀態:我們應該讓我們的寫的代碼永遠處于就緒態和運行態之間切換
    上述概念的組合:最高效的一種組合就是異步非阻塞

    四 開啟進程的兩種方式

    定心丸:代碼開啟進程和線程的方式,代碼書寫基本是一樣的,你學會了如何開啟進程就學會了如何開啟線程
    第一種

    from multiprocessing import Process
    import time
    
    
    def task(name):
        print('%s is running'%name)
        time.sleep(3)
        print('%s is over'%name)
    
    
    if __name__ == '__main__':
        # 1 創建一個對象
        p = Process(target=task, args=('jason',))
        # 容器類型哪怕里面只有1個元素 建議要用逗號隔開
        # 2 開啟進程
        p.start()  # 告訴操作系統幫你創建一個進程  異步
        print('主')
    

    第二種方式 類的繼承

    from multiprocessing import Process
    import time
    
    
    class MyProcess(Process):
        def run(self):
            print('hello bf girl')
            time.sleep(1)
            print('get out!')
    
    
    if __name__ == '__main__':
        p = MyProcess()
        p.start()
        print('主')
    

    總結

    • 創建進程就是在內存中申請一塊內存空間將需要運行的代碼丟進去
    • 一個進程對應在內存中就是一塊獨立的內存空間
    • 多個進程對應在內存中就是多塊獨立的內存空間
    • 進程與進程之間數據默認情況下是無法直接交互,如果想交互可以借助于第三方工具、模塊

    五 join方法

    join是讓主進程等待子進程代碼運行結束之后,再繼續運行。不影響其他子進程的執行

    from multiprocessing import Process
    import time
    
    
    def task(name, n):
        print('%s is running'%name)
        time.sleep(n)
        print('%s is over'%name)
    
    
    if __name__ == '__main__':
        # p1 = Process(target=task, args=('jason', 1))
        # p2 = Process(target=task, args=('egon', 2))
        # p3 = Process(target=task, args=('tank', 3))
        # start_time = time.time()
        # p1.start()
        # p2.start()
        # p3.start()  # 僅僅是告訴操作系統要創建進程
        # # time.sleep(50000000000000000000)
        # # p.join()  # 主進程等待子進程p運行結束之后再繼續往后執行
        # p1.join()
        # p2.join()
        # p3.join()
        start_time = time.time()
        p_list = []
        for i in range(1, 4):
            p = Process(target=task, args=('子進程%s'%i, i))
            p.start()
            p_list.append(p)
        for p in p_list:
            p.join()
        print('主', time.time() - start_time)
    

    進程之間數據相互隔離

    from multiprocessing import Process
    
    
    money = 100
    
    
    def task():
        global money  # 局部修改全局
        money = 666
        print('子',money)
    
    
    if __name__ == '__main__':
        p = Process(target=task)
        p.start()
        p.join()
        print(money)
    
    版權聲明:本文為wg14747421417原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/wg14747421417/article/details/105691239

    智能推薦

    asp.net做一個簡易的聊天室

    要求: 結果: 關鍵代碼: Default.aspx Default.aspx.cs Default2.aspx Default2.aspx.cs Default3.aspx Default3.aspx.cs Default4.aspx...

    動態SQL和多表關聯-筆記

    《動態SQL與多表關聯》筆記 學習目標 能夠使用動態SQL完成SQL拼接 能夠使用resultMap完成多表查詢 能夠使用一對一查詢 能夠使用一對多查詢 (注:多對多其實就是兩個一個多) 映射文件:為什么要resultMap 目標 定義結果映射 使用結果映射 回顧 在mybatis中有2種配置文件: 核心配置文件,如:sqlMapConfig.xml 實體類映射文件,如:UserMapper.xm...

    【OpenGL C++ UE4】獲取模型頂點及面索引數據,并優化存儲結構供UE4繪制

    目錄 一、功能需求 二、成果 三、環境配置 四、詳細步驟 4.1 Max制作三棱錐并處理 4.2 核心代碼 4.2.1 傳入結構體數據 4.2.2 頂點去重、更新索引 4.2.3 輸出本地CSV文件 4.3 UE4繪制 一、功能需求 想必你肯定會問我一個問題,UE4直接導入模型不好么? 哈哈,前提是在做畢設時,導師提供的只有頂點與面索引數據,沒有模型。 下文詳細介紹了畢設開發中的難點,涉...

    解決Pyinstaller打包numpy和pandas庫文件過大問題

    解決Pyinstaller壓縮numpy和pandas庫文件過大問題 文件包類型和網上的方法 Windows下docker的安裝 在docker下實現打包     今天是2021年的第一天,先祝各位小伙伴現年快樂哈。最近因為做了一個項目,需要打包文件,文件中包含了numpy和pandas庫,結果打包出來幾百行的代碼居然要900m,人都傻了,翻遍了全網找解決方...

    猜你喜歡

    【混沌工程】基于ChaosBlade實現網絡故障模擬

    一、前言 很久之前曾基于linux內核自帶的TC和netem模擬一些公網中遇到的極端情況(延遲、丟包、重復、損壞和亂序等),驗證了我們傳輸程序的健壯性! 具體細節可見這篇老博客: https://blog.csdn.net/u013128262/article/details/84784663 最近在復現kafka生產端一個timeout異常場景時,發現之前方案時因為內核和OS版本問題有些差異而無...

    使用FileZilla連接時超時,無法連接到服務器

    用FileZilla連接服務器時,顯示錯誤: 解決方法: 檢查基本的內容 主機是否寫錯 端口是否自定義,默認21 檢查用戶名和密碼是否錯誤 如果連接的是公司內網 使用ping命令,測試一下是否能收到數據 收不到則需要開啟VPN,再ping,看是否能接收數據(請老鐵們用自己最合適的方法解決) 如果開啟VPN后能接收數據,則可以連接一下服務器,如果不行(怎么可能不行),則跳轉3并依次嘗試 開啟VPN后...

    反匯編:結構體拷貝傳參

    一、結構體拷貝傳參 二、引用和常引用傳參 三、大結構體做形參/數組拷貝...

    羊城杯web(eazyphp)

    題目環境 file_put_contents() file_put_contents() 函數把一個字符串寫入文件中 構造payload 在 url 中傳參 蟻劍連接拿到flag...

    精品国产乱码久久久久久蜜桃不卡