python編程之進程
阿新 • • 發佈:2018-02-04
print 自己 div 參數 阻塞 eas 什麽 但是 就會
進程:運行中的程序
進程和操作系統的關系:進程是操作系統調度和資源分配的最小單位,是操作系統的結構基礎。
那麽為什麽要有進程呢?
程序在運行時,會使用各種硬件資源,如果他們之間沒有界限,那麽程序之間的數據必然會產生混亂。所以為了實現資源的隔離,就有了進程的概念。
進程的調度方式:
1,先到先服務算法(FCFS)
先請求的進程就先進行處理。缺點:大作業先到,就會使後面的短作業不能得到及時處理。
2,短作業優先算法
處理起來簡短的作業先進行處理。缺點:一些大的作業將會長時間得不到處理。
3,時間片輪轉算法
給每個進程分配時間片,然後輪轉者進行處理。缺點:一些重要任務將無法及時處理。
4,多級反饋算法
處理分多個級別,由高到低,高級別先執行,但是級別越低分配的時間越長。當一個進程進來時,先按FCFS在最高級別排隊,當其在時間片內沒有執行完成時,就把它放進下一個級別的,依次類推。因為低級別分配的時間更長,長進程就能得到更多的資源來完成處理。
進程的並行和並發
並行:多核處理器,同時進行多個進程的工作
並發:資源有限的情況下,比如單核處理器,多個進程交替使用資源
區別:並行是真正的同時運行,而並發只是宏觀上看起來像是同時運行
進程的同步和異步
同步
import time from multiprocessing import Process # multiprocessing模塊:綜合處理進程的包def func(): time.sleep(1) return ‘同步‘ if __name__ == ‘__main__‘: p = Process(target=func) ret = func() print(ret) # 像這種上個工作完成下面才能進行的,就叫做同步進程
異步
import time from multiprocessing import Process # multiprocessing模塊:綜合處理進程的包 def func(): time.sleep(1) print(‘子進程‘) # 後打印if __name__ == ‘__main__‘: p = Process(target=func) # 創建一個進程對象 參數target傳函數的名字 p.start() # 開始進程 print(‘父進程‘) # 先打印 # 像這種只是開始一個進程,而不管其結果,就進行自己接下來的工作的,就是異步進程
阻塞和非阻塞
阻塞:需要等待信息才能繼續執行時,是會產生阻塞。例如:input輸入時,time.sleep時等。
import time input(‘>>>‘) print(‘1‘) time.sleep(2) print(‘2‘)
非阻塞:和阻塞相反的狀態。
進程三種狀態之間的轉換
守護進程
守護進程:使守護進程在父進程執行完成後就結束,不會像正常的子進程那樣,主進程在執行完成後還要等子進程執行完成。 1,守護進程的開啟設置一定要放在進程開啟之前 2,守護進程中不能再開啟進程
舉例
import time from multiprocessing import Process def func(): while True: time.sleep(10) print(‘過去了10秒‘) if __name__ == ‘__main__‘: p = Process(target=func) p.daemon = True # 一定在進程開啟之前設置 p.start() for i in range(100): time.sleep(1) print(‘*‘*i)
進程的幾個方法和屬性查看
# is_alive和terminate import time from multiprocessing import Process def func(): print(‘1‘) time.sleep(1) print(‘2‘) if __name__ == ‘__main__‘: p = Process(target=func) p.start() print(p.is_alive()) # True 判斷子進程是否還存在 time.sleep(0.1) p.terminate() # 結束子進程 通過操作系統來完成 time.sleep(1) print(p.is_alive())
# pid和name 屬性查看 from multiprocessing import Process def func(): pass if __name__ == ‘__main__‘: p = Process(target=func) p.start() print(p.pid) # 28716 查看子進程的進程id print(p.name) # Process-1 查看子進程的進程名
進程鎖
鎖:在並發編程中,保證數據的安全。使多個進程不能同時對數據進行操作,從而造成數據處理邏輯混亂。
來一個買火車票的例子
創建ticket文件,裏面模擬序列化內容:{"count": 4},定義4張票。
![技術分享圖片](/img/jia.gif)
import time import random import json from multiprocessing import Lock from multiprocessing import Process def search(): with open(‘ticket‘) as f: print(‘票數:%d‘ %json.load(f)[‘count‘]) def get(i): with open(‘ticket‘) as f: ticket_num = json.load(f)[‘count‘] if ticket_num > 0: time.sleep(random.random()) with open(‘ticket‘, ‘w‘) as f: json.dump({‘count‘: ticket_num-1}, f) print(‘%s,買到票了‘ %i) else: print(‘%s,沒有票了‘ %i) def func(i, lock): search() lock.acquire() # 等待人來拿鑰匙開門 沒有人來就阻塞 get(i) lock.release() # 處理完事情後離開關上門並放回鑰匙 if __name__ == ‘__main__‘: lock = Lock() # 創建一個鎖對象 for i in range(10): p = Process(target=func, args=(i, lock)) p.start()進程鎖實例
信號量
信號量:和進程鎖類似它也是限定多進程的並發,但它可以指定能同時進行的進程數,而不單單是一次只能一個。
![技術分享圖片](/img/jia.gif)
import time import random from multiprocessing import Process from multiprocessing import Semaphore def func(p, S): S.acquire() # 和進程鎖相同,等待鑰匙開門 只是這裏同時開了4道門 print(‘%s辦理取錢‘ %p) time.sleep(random.randint(1, 10)) S.release() # 和進程鎖相同,關門並放回鑰匙 print(‘%s完成辦理‘ %p) if __name__ == ‘__main__‘: sem = Semaphore(4) # 創建一個信號量對象,指定能同時接收的信號量為4 for i in range(20): Process(target=func, args=(i, sem)).start()信號量例子
事件
事件:異步阻塞 用於主進程控制其他進程的執行。 1,waite 事件實例化之後默認為阻塞 2,set 將阻塞狀態變為非阻塞 3,clear 將非阻塞狀態變為阻塞 4,is_set 判斷事件的阻塞狀態 True為非阻塞 False為阻塞
![技術分享圖片](/img/jia.gif)
import time import random from multiprocessing import Process from multiprocessing import Event def traffic_light(e): while True: if e.is_set(): time.sleep(3) print(‘紅燈亮‘) e.clear() else: time.sleep(3) print(‘綠燈亮‘) e.set() def car(i, e): e.wait() print(i) if __name__ == ‘__main__‘: event = Event() # 創建一個事件對象 Process(target=traffic_light, args=(event,)).start() for i in range(100): if i % random.randint(2, 5) == 0: time.sleep(random.randint(1, 3)) Process(target=car, args=(i, event)).start()事件例子
隊列
隊列:先進先出 實現不同進程之間的通信 queue = Queue() 不限定隊列的長度 queue = Queue(10) 限定隊列的長度為10 1,put 放入數據 當隊列有限制且數據放滿時,阻塞 2,get 取出數據 當隊列為空時,阻塞
![技術分享圖片](/img/jia.gif)
import time from multiprocessing import Process from multiprocessing import Queue def producer(q): for i in range(50): q.put(‘包子%d‘ %i) def consumer(q): while True: time.sleep(1) print(q.get()) if __name__ == ‘__main__‘: queue = Queue(10) Process(target=producer, args=(queue,)).start() Process(target=consumer, args=(queue,)).start()隊列例子
python編程之進程