1. 程式人生 > >python編程之進程

python編程之進程

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張票。

技術分享圖片
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()
進程鎖實例

  信號量

信號量:和進程鎖類似它也是限定多進程的並發,但它可以指定能同時進行的進程數,而不單單是一次只能一個。
技術分享圖片
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為阻塞
技術分享圖片
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 取出數據 當隊列為空時,阻塞
技術分享圖片
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編程之進程