Day 31 并发编程
目錄
- 并發(fā)編程
- 并發(fā)和串行
- 學習并發(fā)的目的
- 進程是什么
- 操作系統(tǒng)是什么
- 操作系統(tǒng)發(fā)展史
- 第二代計算使用的是批處理系統(tǒng),存在以下三個問題
- 第三代計算機
- 第四代計算機
- 多道技術
- 并發(fā)編程中的重要概念
- python如何使用多進程
- 1. 導入multiprocessing中的Process類 實例化這個類 指定要執(zhí)行的任務target
- 2. 導入multiprocessing中的Process類 繼承這個類 覆蓋run方法 將要執(zhí)行的任務放入run中開啟進程是會自動執(zhí)行該函數(shù)
- 進程之間內存相互隔離
- join函數(shù)
- 進程對象的常用屬性
- 僵尸進程和孤兒進程
并發(fā)編程
并發(fā)和串行
- 程序默認的執(zhí)行方式是串行,即程序自上而下一行一行執(zhí)行,必須把當前任務執(zhí)行完畢才能執(zhí)行下一個任務
學習并發(fā)的目的
就是編寫可以同時執(zhí)行多個任務的程序,從而提高效率
串行和并發(fā)都是程序處理任務的方式
## 實現(xiàn)并發(fā)的方式
進程是什么
進程是指正在運行的程序,是操作系統(tǒng)調度以及進行資源分配的基本單位
當程序從硬盤讀取到內存中運行的時候進程就產(chǎn)生了
多進程:指的是同一時間有多個程序被裝入內存并執(zhí)行
多進程的實現(xiàn)原理其實就是操作系統(tǒng)調度進程的原理
操作系統(tǒng)是什么
操作系統(tǒng)就是一款特殊的軟件
操作系統(tǒng)和普通軟件的區(qū)別:
操作系統(tǒng)的主要功能
GUI圖形化用戶界面
操作系統(tǒng)發(fā)展史
掌握多道技術的實現(xiàn)原理,就是多進程的實現(xiàn)原理
第二代計算使用的是批處理系統(tǒng),存在以下三個問題
第三代計算機
使用SPOOLING聯(lián)機計數(shù)
多終端多用戶
第四代計算機
大規(guī)模集成電路+多用戶多終端
特點:具備GUI圖形化界面,普通人也可以使用
多道技術
實現(xiàn)原理:
空間復用
? 同一時間加載多個任務到內存中,多個進程之間的內存區(qū)域需要相互隔離,這種隔離是物理隔離,為了保證數(shù)據(jù)安全性
時間復用
? 操作系統(tǒng)會在多個進程之間做切換
? 切換進程的兩種情況:
? 1.但給一個進程遇到IO操作時會自動切換
? 2.當任務執(zhí)行時間過長(超時)強制切換
? 切換進程前需要記錄當前進程的狀態(tài),同時頻繁的切換也消耗系統(tǒng)資源
? 當所有任務沒有IO操作時,切換執(zhí)行反而降低了效率,但是為了保證并發(fā)執(zhí)行必須要犧牲效率
多道技術總結:切換+保存
有了多道技術,計算機就可以同時并發(fā)處理多個任務
并發(fā)編程中的重要概念
串行:從上到下依次執(zhí)行
并發(fā):多個任務同時執(zhí)行,本質是多個進行不斷在切換,由于切換速度快,所以感覺是同時運行
并行:真正意義上的同時運行,有幾個核心就能并行幾個任務,如果超過核心數(shù)就使用并發(fā)執(zhí)行
以上三個都是用于描述處理任務的方式
一個進程的三種狀態(tài)
阻塞:當程序遇到IO操作,無法繼續(xù)執(zhí)行代碼時的一種狀態(tài)
非阻塞 :程序沒有遇到IO操作的狀態(tài),正常運行
就緒:程序等待CPU運行
阻塞非阻塞也可以用來描述執(zhí)行任務的方式
三種狀態(tài)的互相切換
程序正常運行,當運行時間超過閾值,會進入就緒狀態(tài),等待cpu執(zhí)行完其他的進程后,恢復到運行狀態(tài)繼續(xù)執(zhí)行
當程序遇到IO操作,會進入阻塞狀態(tài),當結束阻塞狀態(tài)后,程序會進入就緒狀態(tài),等待cpu空閑后繼續(xù)執(zhí)行本程序
野指針和僵尸指針
野指針:內存中的地址被刪除
僵尸指針:內存中的地址因為某種原因沒有被清除
進程的創(chuàng)建和銷毀
創(chuàng)建:
銷毀:
進程和程序
程序是一堆代碼存放在文件中
進程就是程序中的代碼從硬盤讀入內存后產(chǎn)生的
進程是由程序產(chǎn)生的
一個程序可以產(chǎn)生多個進程,每一個進程都有一個唯一的PID
進程的層次結構
在linux中進程具備父子關系,是一個樹狀結構,可以相互查找到對方
在windows中,沒有層級關系,父進程可轉讓子進程的句柄
父進程與子進程:例如qq打開了瀏覽器,qq就是父進程,瀏覽器就是子進程
PID和PPID
PID是當前進程的編號
PPID是當前程序的父進程的編號
我們運行py文件的時候其實是運行python解釋器,所以運行py文件的父進程就是python解釋器
import os os.getpid() os.getppid()python如何使用多進程
1. 導入multiprocessing中的Process類 實例化這個類 指定要執(zhí)行的任務target
import os from multiprocessing import Processdef task():print("this is sub process")print(f"sub process id {os.getpid()}" )if __name__ == '__main__':p = Process(target=task)p.start() print("this is parent process")print(f"parent process is: {os.getpid()}")print("over")linux和windows開啟進程的方式區(qū)別
linux會將父進程的內存數(shù)完整復制一份給子進程
windows會導入父進程的代碼,從新執(zhí)行一遍,來獲取需要處理的任務,所以在編寫代碼時如果是windows,需要把開啟進程的代碼放在main判斷中
2. 導入multiprocessing中的Process類 繼承這個類 覆蓋run方法 將要執(zhí)行的任務放入run中開啟進程是會自動執(zhí)行該函數(shù)
from multiprocessing import Process import osclass Downloader(Process):def __init__(self,url,size,name):super().__init__()self.url = urlself.size = sizeself.name = namedef run(self):print(os.getpid())passif __name__ == '__main__':m = Downloader()m.start()print("parent over",os.getpid())進程之間內存相互隔離
from multiprocessing import Process import os,timea = 257def task():global aprint("2",a,id(a))a = 200if __name__ == '__main__':p = Process(target=task)p.start() time.sleep(4)print(a)join函數(shù)
就是讓主進程等待子進程運行完再執(zhí)行
from multiprocessing import Process import timedef task1(name):for i in range(10000):print(f'{name} run')def task2(name):for i in range(100):print(f'{name} run')if __name__ == '__main__': p1 = Process(target=task1,args=("p1",))# args 是給子進程傳遞的參數(shù) 必須是元組p1.start() p2 = Process(target=task2,args=("p2",))p2.start() p2.join() p1.join()print("over")進程對象的常用屬性
if __name__ == '__main__':p = Process(target=task,name="老司機進程")p.start()# p.join()# print(p.name)# p.daemon #守護進程# p.join()# print(p.exitcode) # 獲取進程的退出碼 就是exit()函數(shù)中傳入的值# print(p.is_alive()) # 查看進程是否存活# print("zi",p.pid) # 獲取進程id# print(os.getpid())# p.terminate() #終止進程 與strat 相同的是 不會立即終止,因為操作系統(tǒng)有很多事情要做 # print(p.is_alive())僵尸進程和孤兒進程
孤兒進程:當父進程已經(jīng)結束,而子進程還在運行,子進程就成為孤兒進程,孤兒進程有其存在的意義,沒有不良影響,孤兒進程會被操作系統(tǒng)接管
僵尸進程:當一個進程已經(jīng)結束了,但是他仍然還有一些數(shù)據(jù)存在,此時稱之為僵尸進程
在linux中,有這么一個機制,父進程無論什么時候都可以獲取到子進程的一些數(shù)據(jù);子進程任務執(zhí)行完畢后,確實結束了但是仍然保留了一些數(shù)據(jù),目的是為了讓父進程能夠獲取這些信息;linux中,可以調用waitpid來徹底清除子進程的殘留信息
python中已經(jīng)封裝了處理僵尸進程的操作
轉載于:https://www.cnblogs.com/masterjian924/p/11124038.html
總結
以上是生活随笔為你收集整理的Day 31 并发编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 老雷socket编程之PHP利用sock
- 下一篇: nginx conf 文件