進程一

来源:https://www.cnblogs.com/12345huangchun/archive/2018/11/28/10034715.html
-Advertisement-
Play Games

一、什麼是進程 進程(Process)是電腦中的程式關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。在早期面向進程設計的電腦結構中,進程是程式的基本執行實體;在當代面向線程設計的電腦結構中,進程是線程的容器。程式是指令、數據及其組織形式的描述,進程是程 ...


一、什麼是進程

  進程(Process)是電腦中的程式關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。在早期面向進程設計的電腦結構中,進程是程式的基本執行實體;在當代面向線程設計的電腦結構中,進程是線程的容器。程式是指令、數據及其組織形式的描述,進程是程式的實體。我們自己在python文件中寫了一些代碼,這叫做程式,運行這個python文件的時候,這叫做進程。

  狹義定義:進程是正在運行的程式的實例(an instance of a computer program that is being executed)。

  廣義定義:進程是一個具有一定獨立功能的程式關於某個數據集合的一次運行活動。它是操作系統動態執行的基本單元,在傳統的操作系統中,進程既是基本的分配單元,也是基本的執行單元   1,進程的概念   第一,進程是一個實體。每一個進程都有它自己的地址空間,一般情況下,包括文本區域(text region)(python的文件)、數據區域(data region)(python文件中定義的一些變數數據)和堆棧(stack region)。文本區域存儲處理器執行的代碼;數據區域存儲變數和進程執行期間使用的動態分配的記憶體;堆棧區域存儲著活動過程調用的指令和本地變數。   第二,進程是一個“執行中的程式”。程式是一個沒有生命的實體,只有處理器賦予程式生命時(操作系統執行之),它才能成為一個活動的實體,我們稱其為進程。進程是操作系統中最基本、重要的概念。是多道程式系統出現後,為了刻畫系統內部出現的動態情況,描述系統內部各道程式的活動規律引進的一個概念,所有多道程式設計操作系統都建立在進程的基礎上。
  2,進程的特征     動態性:進程的實質是程式在多道程式系統中的一次執行過程,進程是動態產生,動態消亡的。     併發性:任何進程都可以同其他進程一起併發執行     獨立性:進程是一個能獨立運行的基本單位,同時也是系統分配資源和調度的獨立單位;     非同步性:由於進程間的相互制約,使進程具有執行的間斷性,即進程按各自獨立的、不可預知的速度向前推進     結構特征:進程由程式、數據和進程式控制制塊三部分組成。     多個不同的進程可以包含相同的程式:一個程式在不同的數據集里就構成不同的進程,能得到不同的結果;但是執行過程中,程式不能發生改變。   註意:同一個程式執行兩次,就會在操作系統中出現兩個進程,所以我們可以同時運行一個軟體,分別做不同的事情也不會混亂

二、併發與並行,同步與非同步

  併發:偽並行,就是幾個進程共用一個cpu,幾個進程之間是時間輪換的,而這個輪換時間很短,肉眼是看不到的,所以我們肉眼看到的是幾個進程同時在進行,其他中間有停止的,只是停止時間短,這就叫併發

  並行:指一個進程就用一個cpu,每個進程是沒有停止的,就是一起運行的

  同步:一個任務執行完後,另一個任務才能開始執行,就是有一個任務需要等待,這樣兩個任務之間的關係是同根生的,非常緊密的

  非同步:兩個任務之間沒有關聯,你執行你的,我執行我的,互相不用等待

三、進程的創建方法

  1,方法一

from multiprocessing import Process            #引入進程模塊,
import os,time
def fun1():
    time.sleep(2)
    print('jjjj')
def fun2():
    time.sleep(3)
    print('ddada')
    print(os.getpid())                #獲得子進程的進程id
    print(os.getppid())                #獲得子進程的父進程,即主進程的id
if __name__=="__main__":            #記住,必須用  if  main 
    start_time=time.time()           #開始時間
    p=Process(target=fun2)             #創建一個子進程
    p.start()                         #開始子進程
    fun1()
    print(os.getpid())               #獲得主進程的進程id
    end_time=time.time()              #結束時間
    print(end_time-start_time)          #列印總共用時
整段程式走完用時2秒多一點,但是如果我們按照以前的寫法,先執行fun1(),再執行fun2(),至少得花5秒

  2,方法二

from multiprocessing import Process       #同樣引入模塊
import time
class Mypro(Process):                 #創建一個類,繼承Process
    def __init__(self,name):
        super().__init__()
        self.name=name
    def run(self):                 #這是必須的方法,然後要執行的程式寫在方法裡面就行
        time.sleep(3)
        print(self.name)
if __name__ == '__main__':        #記住,這裡必須寫 if main
    p1=Mypro('huangchun')         #用自己定義的類創建一個子進程
    p1.start()                    #子進程開始
    p1.join()                    #這是join方法,這樣寫就是join後面的主進程程式必須等子進程執行完後在執行,兩種方法都可以用
    print('我是主進程,哈哈哈哈哈哈。。。。。')

四、守護進程

  把一個子進程設為守護進程之後,每當主進程執行完畢後,不管你子進程有沒有執行完畢,都要跟著結束

from multiprocessing import Process
import time
def fun():
    time.sleep(5)
    print('我是子進程')
if __name__ == '__main__':
    p=Process(target=fun)
    p.daemon = True            #這就是把子進程設為了守護進程,但是切記,這句代碼必須寫在start()前面
    p.start()
    print('我主進程,哈哈哈哈哈哈')
沒有設置守護進程之前,代碼要執行5秒才結束,等到子進程執行完才結束,但是設置為守護進程之後,代碼瞬間執行完畢,只列印了主進程的內容,而子進程的print直接死了

五、同步鎖(互斥鎖)

  對一段程式設置同步鎖之後,不管你對這段程式開了幾個進程,但只有一個進程能執行代碼,而其他的進程需要等待前面的進程結束之後才能執行這段代碼,就相當於把開的幾個進程搞成同步了,互相約束著

這是模擬搶火車票的情景,在還沒付錢確認之前,大家都看見了有一張票,但是只有一個人能搶到票
from
multiprocessing import Process,Lock #引入Lockmok import time def fun1(i): #這是查看餘票的方法 with open('piao.txt',mode='r',encoding='utf-8')as f1: num=f1.read() print('%s客戶看到票還有%s張'%(i,num)) def fun(i,lo): #這是買票的方法 time.sleep(1) lo.acquire() #這是同步鎖的開始, with open('piao.txt',mode='r',encoding='utf-8')as f1: num=f1.read() if num=='1': print('%s買到票了'%i) num=int(num)-1 elif num=='0': print('%s沒票了'%i) with open('piao.txt', mode='w', encoding='utf-8')as f1: f1.write(str(num)) lo.release() 這是同步鎖的結束 if __name__ == '__main__': lo=Lock() #這是創建一把鎖 for i in range(10): #這是迴圈創建10個客戶 fun1(i) #這是客戶查看餘票 p=Process(target=fun,args=(i,lo)) #創建子進程去搶票,然後把鎖傳給進程 p.start()
同步鎖把搶票的程式鎖起來了,所以,雖然有10個客戶都在搶票,但實際上只有一人能進入搶票程式,其他的人要等待第一個進搶票程式的人執行完後才能又進一個人,反正每次就只允許一個人在使用搶票程式,其他的人繼續排隊

六、信號量

  信號量就是對一段程式設定允許最多幾個人使用,相當於一個飯店,只有四個位置,最多允許四個人吃飯,後面人要等待前面的人吃完才能進入飯店吃,前面走一個,就可以進一個

from multiprocessing import Process,Semaphore      #引入Semaphore模塊
import time
def fun(s,i):                    
    s.acquire()
    print('%s客戶在吃'%i)
    time.sleep(1)
    print('%s客戶吃完了'%i)
    time.sleep(1)
    s.release()
if __name__ == '__main__':
    s=Semaphore(4)          #創建信號量對象
    for i in range(10):          #迴圈創建10個人去飯店吃飯
        p=Process(target=fun,args=(s,i)) #創建飯店子進程,然後把信號量傳給子進程
        p.start()

七、事件

  在創建事件之後預設值為False,我們可以把創建的事件對象傳給子進程,然後在子進程中事件對象.set(),使得指變為Ture。然後我們在主進程中加上事件對象.wait(),在此處,只有當值為Ture時不會阻塞,值為False就會阻塞,

從而我們可以用此方法來影響主進程的執行。

from multiprocessing import Process,Event   #引入Event模塊
import time
def func(e):
    print('子進程開始執行')
    time.sleep(3)
    print('子進程結束')
    e.set()                      #設置事件值為Ture,我們還可以通過e.clear()把值改為False
if __name__ == '__main__':
    e=Event()                   #創建事件對象e,此時預設值為False
    p=Process(target=func,args=(e,))       #創建子進程,把e傳給子進程
    p.start()
    print('等待子進程結束後拿到值')
    e.wait()                    #當值為False會阻塞,當值為Ture是,不會阻塞,因為我們在子進程中最好把值改為Ture,所以wait()以後的程式要等到子進程執行完才能執行
    print('拿到值,執行主進程')
    time.sleep(1)
    print('主進程執行完畢')

八、隊列,消費者生產者模型,joinablequeue

  1,隊列

  隊列就相當於一個容器,裡面可以放數據,特點是先放進去先拿出來,即先進先出,

from multiprocessing import Queue       #引入Queue模塊
q=Queue(2)                           #創建一個隊列對象,並給他設置容器大小,即能放幾個數據
q.put(1)                             #put()方法是往容器里放數據
q.put(2)
q.put(3)                             #這是往容器里放第三個數據,由於只能放兩個,所以此處會阻塞,不會報錯,相當於死迴圈
q.put_nowait(4)                      #put_nowait()這也是從容器里放數據的方法,但如果容器滿了,不會阻塞,會直接報錯
q.get()                              #get()方法是從容器里拿數據
q.get()
q.get()                              #這是從容器里拿第三個數據,但是容器的兩個數據拿完了,沒有數據了,此時也會阻塞,不會報錯,死迴圈
q.get(False)                         #這也是從容器里拿數據的方法,當沒數據時不會阻塞,直接報錯
q.get_nowait()                       #這也是從容器里拿數據的方法,當沒數據時不會阻塞,直接報錯
q.full()                             #這是查看容器是否滿了,如果滿了,返回Ture,否則返回False
q.empty()                             #這是查看容器是否為空,如果為空,返回Ture,否則返回False

  2,消費者生產者模型

  就是消費者和生產者之間不是直接聯繫的,而是通過中間的一個隊列來進行聯繫的,生產者把生產的東西放進進隊列里,消費者從隊列里拿東西,其實消費者和生產者之間沒有實質的聯繫

from multiprocessing import Process,Queue
import time
def sheng(q):              #生產者
    for i in range(10):
        time.sleep(1)
        q.put(i)
        print('包子%i生產完畢'%i)
    q.put('over')
def xiao(q):             #消費者
    while 1:
        time.sleep(1.5)
        ss=q.get()
        if ss=='over':
            break
        print('包子%s被吃了'%ss)
if __name__ == '__main__':
    q=Queue(10)           #創建隊列對象q
    p=Process(target=sheng,args=(q,))        #創建生產者子進程,把q傳給他
    p1=Process(target=xiao,args=(q,))        #創建消費者子進程,也把q傳給他
    p.start()
    p1.start()
有個問題就是,生產者要把生產結束的消息放進隊列里,讓消費者過去結束消息,消費者才知道隊列里沒有數據了,這樣消費者才能停止,如果生產者不放結束消息,當生產者結束時,即不往隊列放數據,而消費者不知道生產者已經結束,
還一直往隊列拿數據,當隊列沒數據時,消費者一邊就會阻塞。解決阻塞,有幾個消費者,生產者就應該放幾個結束消息,讓每個消費者都知道,這樣每個消費者才能結束。但是生產者又不知道有幾個消費者,所以不知奧應該放幾個結束數據,
這樣就無法解決對消費者現象。此時,我們就就可以引入joinablequeue

  3,joinablequeue

  他其實就是一種隊列,但她又比隊列要多兩種方法,task_done()和join()方法,正是有這兩種方法就可以解決上面的問題

from multiprocessing import Process,JoinableQueue      #引入joinableQueue模塊
import time
def sheng(q):        #生產者
    for i in range(10):
        time.sleep(1)
        q.put(i)
        print('包子%i生產完畢'%i)
    q.join()                   #當q收到的task_done數量等於放進q的數據數量時,生產者就結束了
def xiao(q,i):                    #消費者
    while 1:
        time.sleep(1.5)
        ss=q.get()
        if ss=='over':
            break
        print('%s客戶吃包子%s'%(i,ss))
        q.task_done()                  #消費者每從q里取一個值,就向q返回一個task_done消息
if __name__ == '__main__':
    q=JoinableQueue()                   #創建joinablequeue對象q
    p=Process(target=sheng,args=(q,))    #創建生產者子進程,把q傳給他
    p.start()
    for i in range(3):                      #迴圈創建消費者子進程,把q傳給他
        p1=Process(target=xiao,args=(q,i))
        p1.daemon=True                   #把創建的每個消費者子進程設為守護進程
        p1.start()
    p.join()                              #主進程要等到生產者子進程結束後才結束
整個個過程就是:生產者生產了10個包子,3個消費者吃包子,沒吃一個包子往q里發一個task_done,當q擁有10個task_done時,意味著10個包子吃完了,此時,生產者就結束了,接著主進程也也結束了,然後守護進程跟著結束了,即所有的消費者子進程結束,解決上面所遇到的問題

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 好記憶不如爛筆頭: ...
  • redis-cachecloud https://github.com/sohutv/cachecloud/wiki/3.%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AB%AF%E6%8E%A5%E5%85%A5%E6%96%87%E6%A1%A3 ...
  • DNS DomainNameSystem功能變數名稱系統,根據功能變數名稱查出IP地址 1.dig命令可以顯示整個查詢的過程 root@VM-38-204-ubuntu:~# dig www.sopans.com //這一段是查詢參數和統計 ; > DiG 9.10.3-P4-Ubuntu > www.sopans... ...
  • """提示:代碼中的內容均被註釋,請參考,切勿照搬""" """註意:代碼切勿照搬,錯誤請留言指出""" ...
  • 題意 "題目鏈接" Sol 一開始的思路:新建一個虛點向每個點連邊,再加上題面中給出的邊,邊權均為大小 需要購買的數量 然後發現死活都過不去 看了題解才發現題目中有個細節——買了$A$就可以買$B$,但是人家沒告訴你必須買夠$A$的數量才能買$B$呀qwqqqqqqq 所以建圖的時候只算一次貢獻就行 ...
  • 這裡有兩張表TableA和TableB,分別是姓名錶和年齡表,用於我們例子的測試數據: 表連接有幾種? sql表連接分成外連接、內連接和交叉連接。 一.外連接 概述: 外連接包括三種,分別是左外連接、右外連接、全外連接。 對應的sql關鍵字:LEFT/RIGHT/FULL OUTER JOIN,通常 ...
  • pip安裝使用 i參數指定源 指定豆瓣源,快如閃電:pip install i http://pypi.douban.com/simple/ 使用sys.modules查看導入包的路徑 sys.modules是一個全局字典,可以通過它來瞭解當前環境載入了什麼包,包的路徑 ...
  • Kibana安裝及使用說明 Kibana是一個針對Elasticsearch的開源分析及可視化平臺,用來搜索、查看交互存儲在Elasticsearch索引中的數據。 官方地址:https://www.elastic.co/cn/products/kibana 一、Kibana安裝 1.環境準備 Ki ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...