并發編程 【筆記1】
多任務編程
利用多進程與多線程提高程序運行效率(充分利用cpu多核資源,同時處理多個應用程序任務)
進程? process
理論:
定義:程序在計算機中的一次運行
程序是一個可執行的文件,占有磁盤
進程是一個動態過程的描述,占有內存資源,有一定的生命周期
系統如何產生一個進程?
用戶調用命令發起請求(命令窗口輸入命令)
用戶調用程序接口(點擊圖標這個過程)
系統接收用戶請求,開始創建進程(點開圖標后系統該干的事)
系統將創建的進程提供用戶使用(點開圖標后系統該干的事)
系統調配計算機資源,確定進程狀態等(開機或點開圖標后系統該干的事)
進程基本概念:
cpu時間片:一個進程占有cpu內核說明這個進程在cpu時間片上
pcb(進程控制塊):用于存放進程的基本信息,用于系統查找并識別進程,存放在內存中
進程id(pid):系統為每一個進程分配一個大于0的整數,作為進程id,每個進程id不重復
父子進程:系統中每一個進程(除了系統初始化進程)都有唯一的父進程,可以有多個子進程,父子進程關系便于進程管理
進程狀態? ? ? ?1.就緒態:等待分配cpu,進程具備執行條件? ? ? ? 2.運行態:進程占有cpu時間片? ? ? ?3等待態:讓出cpu,停止運行? ? ? ?4.新建:創建一個進程,獲取資源? ? ? ? 5.終止:進程結束,釋放資源
進程的運行狀態:1.多進程可以跟充分使用計算機多核資源? 2.進程之間的運行互不影響,互相獨立? 3.每個進程擁有獨立的空間,各子使用自己空間資源
基于fork的多進程編程
fork的使用
pid = os.fork() ''' 功能:獲取進程的pid值 返回值:成功會在原有進程返回新進程的pid新進程返回0,失敗會返回一個負數 '''
注意:
子進程會復制父進程全部內存空間,從fork下一句代碼開始執行
父子進程各自獨立運行,運行不一定有順序
利用父子進程fork返回值的區別,配合if讓父子進程執行不同的內容,但還是固定的搭配
父子進程有各自特有特征
父進程fork之前開辟的空間子進程同樣擁有,但對各自空間的操作互不影響
進程相關函數
os.getpid() ''' 功能:獲取一個進程的pid 返回值:返回當前進程的pid ''' os.getppid() ''' 功能:獲取父進程的pid 返回值:返回父進程的pid ''' os._exit(status) ''' 功能:結束一個進程 參數:進程的終止狀態 ''' sys.exit([status]) ''' 功能:推出進程 參數:整數,表示推出狀態 字符串:表示推出時打印內容 '''
孤兒與僵尸
孤兒:父進程比子進程退出的更早,子進程變成孤兒進程,孤兒進程被系統進程收養,系統進程變成父進程,孤兒進程會自動推出系統進程
僵尸:子進程比父進程退出的跟早,父進程沒有處理子進程的退出狀態,此時的子進程為僵尸進程,僵尸進程會殘留部分pcbzai內存中,浪費內存
避免僵尸進程:
wait函數
pid, status = os.wait() ''' 功能:在父進程中阻塞等待處理僵尸進程 返回值:pid 推出的子進程的pid status 子進程是否退出 '''
二級子進程
父進程創建子進程,等待回收
子進程創建二級子進程后退出
二級子進程為孤兒,和父進程一起執行
通過信號處理子進程退出
import singal singal.singal(singal.SIGCHLD,singal.SIG_IGN) ''' 原理:子進程退出時會發信號給父進程,如果父進程忽略子進程信號,系統會自動處理子進程 特點:不會影響父進程運行,可以處理所有子程序退出 '''
multprocessing模塊創建進程
進程創建
'''基本接口''' Process() ''' 功能:創建進程對象 參數:target綁定要執行的目標函數,args元組用于給target函數位置傳參,kwargs字典,給target函數鍵值傳參 ''' p.join([timeout]) ''' 功能:阻塞等待回收進程 參數:超時時間 ''' p.start() ''' 功能:啟動進程,此時target綁定函數開始執行,此函數作為子程序執行內容,此時進程正真被創建 '''
流程:
將子進程執行的事件封裝為函數
通過模塊的Process類創建進程對象,關聯函數
通過進程對象調用start啟動進程
通過進程對象調用join回收進程
p.name //進程名 p.pid //對應子進程的pid號 p.is_alive() //查看子進程是否在生命周期 p.daemon //設置父子進程的退出關系 ''' 如果設置為True則子進程會隨父進程的退出而結束 要求必須在start()前設置 如果deamon設置成True 通常就不會使用join() '''
注意:
使用mutiprocess創建進程同樣是子進程復制父進程空間代碼段,父子進程運行互不影響
子進程只運行target綁定的函數部分,其余內容均是父進程執行內容
mutiprocessing中父進程往往只用來創建子進程回收子進程,具體事件由子進程完成
mutiprocessing創建的子進程中無法使用標準輸入
自定義進程類
1創建步驟:繼承process類,重寫_init_函數添加自己的屬性,使用super()添加父類屬性,重寫run()方法
2使用方法:實例化對象,調用start自動執行run方法,調用join回收線程
進程池實現
1必要性
進程的創建和銷毀過程消耗資源較多
當任務量眾多,每個任務在很短時間內完成時,需要頻繁的創建與銷毀進程,此時計算機壓力較大
2原理:創建一定數量的進程來處理事件,事件處理完后,進程繼續處理其他事件,直到所有事件都處理完畢統一銷毀
from multiprocessing import Pool Pool(processes) ''' 功能:創建進程池對象 參數:指定進程數量,默認根據系統自動判定 ''' pool.apply_async(func,args,kwds) ''' 功能:使用進程池執行func事件 參數:func 事件函數,args元組 給func按位置傳參,kwds字典 給func按照鍵值傳參 返回值:返回函數事件對象 ''' pool.close() ''' 功能:關閉進程池 ''' pool.join() ''' 功能:回收進程池中進程 '''
多線程
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。