1. 程式人生 > >並發進程

並發進程

-a 獲得 分享圖片 鍵盤 內存 邏輯運算 觸發 活著 tar

1.計算機硬件和操作系統

  1. 計算機硬件組成:

    • 主板:固化(寄存器,是直接和cpu進行交互的一個硬件)
    • cpu:中央處理器,能夠進行數學運算和一些邏輯運算,並且控制所有硬件協調工作
    • 存儲:硬盤和內存
    • 輸入設備:鍵盤,鼠標,話筒
    • 輸出設備:顯示器,音響,打印機

  • 早期的計算機是以計算為核心的
  • 現在的計算機是以存儲為核心的

  2.計算機操作系統:

    • 操作系統是一個軟件,是一個能直接操縱硬件的一個軟件
    • 它的目的是讓用戶用起來更加的輕松,高可用,低耦合;
    • 幾個代表性系統:dos windows unix

操作系統的作用:

  • 封裝所有硬件接口,讓各種用戶使用電腦更加輕松;
  • 是對計算機內所有的資源進行合理的調度和分配;

2.進程的理論

  1. 幾個後綴文件:

    • .sh shell腳本文件
    • .out linux系統中的可執行文件
    • .bat 批處理腳本文件
    • .lib 庫文件
    • .dll 庫
    • .exe 可執行文件

  2.進程:

    • 是指正在執行的程序;
    • 是程序執行過程中的一次指令
    • 也可以叫做程序的一次執行過程
    • 進程是一個動態的概念

  3.進程三大部分組成:代碼段,數據段,PCB:進程管理調度

  4.進程的三大基本狀態

    • 就緒狀態:已經獲得運行需要的所有資源,除了cpu
    • 執行狀態:已經獲得了所有資源包括cpu,處於正在執行
    • 阻塞狀態:因為各種原因,進程放棄了cpu,導致進程無法繼續執行;此時進程處於內存中,繼續等待獲取cpu
    • 因為各種原因,進程放棄了cpu,導致進程無法繼續執行,此時進程被踢出內存;

3.關於進程的一些名詞

  • 並行:是指兩者同時執行,一定是多個車道,在同一時間點
  • 並發:是指在資源有限的情況下,兩者輪流使用資源,只有一條賽道
  • 同步:就是一個任務的完成需要依賴另外一個任務時,只有等待被依賴的任務完成後,才能繼續進行,是可靠的任務序列,要麽成功都成功,失敗都失敗,兩個任務的狀態可以保持一致;
  • 異步:不需要等待被依賴的任務完成,只是通知被依賴的任務要完成什麽工作,依賴的任務也會立即執行,至於被依賴的任務最終是否真正完成,依賴它的任務無法確定,所以它是不可靠序列;
  • 技術分享圖片
    同步:比如你去商店買書,你問老板有沒有<古龍小說集>,老板說我給你查查,然後你就一直等,有可能等一天,有可能等一個小時,必須等到一個結果,你才去進行下一步;
    
    異步:還是你去買書,你問老板有沒有,老板說,你先回去吧,我幫你查查,有了電話通知你,你得到一個結果,可是這個結果並不是真實的結果,只是一個反饋結果而已;
    
    阻塞:還是買書,你問老板有沒有,老板說我幫你查查,然後你會一直在等,等到天荒地老,什麽也不幹,等一個結果;
    
    非阻塞:還是買書,你問老板有沒有,老板說我幫你查查,你說老板你先查著,我先玩一會,然後你一會在過來看看;
    例子
  • 阻塞與非阻塞:阻塞和非阻塞這兩個概念與程序(線程)等待消息通知(無所謂同步或者異步)時的狀態有關。也就是說阻塞與非阻塞主要是程序(線程)等待消息通知時的狀態角度來說的
  • 技術分享圖片
    同步阻塞形式
      效率最低。拿上面的例子來說,就是你專心排隊,什麽別的事都不做。
    
    異步阻塞形式
      如果在銀行等待辦理業務的人采用的是異步的方式去等待消息被觸發(通知),也就是領了一張小紙條,假如在這段時間裏他不能離開銀行做其它的事情,那麽很顯然,這個人被阻塞在了這個等待的操作上面;
    
      異步操作是可以被阻塞住的,只不過它不是在處理消息時阻塞,而是在等待消息通知時被阻塞。
    
    同步非阻塞形式
      實際上是效率低下的。
    
      想象一下你一邊打著電話一邊還需要擡頭看到底隊伍排到你了沒有(兩個操作不能同時執行,因為是同步),如果把打電話和觀察排隊的位置看成是程序的兩個操作的話,這個程序需要在這兩種不同的行為之間來回的切換,效率可想而知是低下的。
    
    異步非阻塞形式
      效率更高,
    
      因為打電話是你(等待者)的事情,而通知你則是櫃臺(消息觸發機制)的事情,程序沒有在兩種不同的操作中來回切換。
    
      比如說,這個人突然發覺自己煙癮犯了,需要出去抽根煙,於是他告訴大堂經理說,排到我這個號碼的時候麻煩到外面通知我一下,那麽他就沒有被阻塞在這個等待的操作上面,自然這個就是異步+非阻塞的方式了。
    四個名詞

4. multiprocessing.Process模塊

1.進程兩種開啟方式:實例化一個進程的對象:

def func():
    print(子進程1的爸爸是%s,我是%s % (os.getppid(),os.getpid()))
def func2():
    print(子進程2的爸爸是%s,我是%s % (os.getppid(), os.getpid()))

if __name__ == __main__:
    li = [func, func2]
    for i in li:
        p = Process(target=i)
        p.start()
    print(主進程的爸爸是%s,我自己是%s % (os.getppid(),os.getpid()))

#主進程的爸爸是1116,我自己是12760
子進程1的爸爸是12760,我是848
子進程2的爸爸是12760,我是11588

2.通過繼承

class Myprocess(Process):
    def __init__(self,name):
        super(Myprocess, self).__init__()
        self.name = name
    def run(self):
        print(這是以繼承類的方式開啟的子進程%s,他的名字是%s %(os.getppid(),self.name))

if __name__ == __main__:
    p = Myprocess(alex)
    p.start()
    print(這裏是主進程%s % os.getpid())

3.進程的常用方法

  1. start() 開啟一個子進程
  2. join() 異步變同步(就是讓父進程停留在join這句話,等待子進程執行結束)
  3. is_alive()判斷進程是否還活著
  4. terminate()殺死進程

每個方法的代碼演示:

技術分享圖片
from multiprocessing import Process
import time

def func():
    for i in range(500):
        time.sleep(0.01)
        print(兒子在這裏)

if __name__ == __main__:
    p = Process(target=func)
    p.start()
    p.join()# 是讓主進程等待子進程執行完。  現象:主進程執行到這句話,主進程阻塞住,等待子進程執行
    for i in range(100):
        time.sleep(0.01)
        print(爸爸在這裏)

# 開啟一個正常的子進程,父進程會等待子進程結束後,父進程也就是程序才結束
# p.join()# 是讓主進程等待子進程執行完。  現象:主進程執行到這句話,主進程阻塞住,等待子進程執行
# 如何把父進程和子進程之間的關系變為同步或者異步?
# 父進程執行join,就會變成同步,不執行join,父進程和子進程就是異步的關系
# join必須放在start()後邊
join和start

技術分享圖片
from multiprocessing import Process
import time


def func():
    time.sleep(1)
    print(123)


if __name__ == __main__:
    p = Process(target=func,)
    p.start()
    p.terminate()# 殺死p進程,讓解釋器告訴操作系統,請殺掉p進程。
    print(子進程是否還活著?, p.is_alive())
    time.sleep(0.002)
    print(子進程是否還活著?, p.is_alive())
    # 返回一個bool值,如果返回True,代表進程還活著,如果返回False,代表子進程死了

# p.is_alive() 判斷p進程是否還活著
# p.terminate() 殺死p進程
is_alive和terminate

4.進程的常用屬性

  • p.name = 給p進程的一個名字
  • p.pid = 返回p進程的pid
  • p.daemon = True 將p進程設置為守護進程(True為守護進程,False為普通進程)
    • 守護進程的兩個特點:
    • 守護進程會隨著父進程的結束而結束
    • 守護進程不能再創建子進程(不能有孩子)

技術分享圖片
from multiprocessing import Process
import time
def func():
    for i in range(10):
        time.sleep(1)
        print(time.strftime("%H:%M:%S"))
if __name__ == __main__:
    #設置為守護進程後,會根據主進程想要的效果停止的子進程
    p = Process(target=func)
    p.daemon = True
    p.start()
    time.sleep(5)
    print(計時結束!)
#輸出結果
20:15:49
20:15:50
20:15:51
20:15:52
20:15:53
20:15:54
計時結束!
守護進程的作用 技術分享圖片
from multiprocessing import Process
import time
import os

def func():
    print(這裏是兒子,兒子的pid是%s%(os.getpid()))

if __name__ == __main__:
    p = Process(target=func)
    p.start()
    p.name = alex
    print(兒子的名字是%s%p.name)
    print(兒子的pid是%s%p.pid)
    print(兒子是不是守護進程?,p.daemon)
其他屬性

並發進程