Python開啟進程的2中方式


 

知識點一:進程的理論
進程:正在進行的一個程序或者說一個任務,而負責執行任務的則是CPU
進程運行的的三種狀態:
1.運行:(由CPU來執行,越多越好,可提高效率)
2.阻塞:(遇到了IQ,3個里面可以通過減少阻塞有效的來提高效率)
3.就緒:(等待CPU來執行的過程)

 

 

知識點二:開啟進程的兩種方式

  開啟進程:開啟進程就是將父進程里面串行執行的程序放到子進程里,實現並發執行,這個過程中,會將父進程數據拷貝一份到子進程。
  運行角度:是2個進程
  注意:子進程內的初始數據與父進程的一樣,如果子進程被創建了被運行了,那么
     子進程里面數據更改對父進程無影響,2個進程是存在運行的

方式一:通過調用multiprocessing模塊下面的Process類方法

#方式一:通過調用multiprocessing模塊下面的Process類方法

'''
p = Process(target=task, args=('子進程',)) :
target=task:指定執行任務的目標是誰   args:后面跟元組,是給target指定函數傳的參數
p=Process(..)相當於是對類Process進行實例化得到了P對象
'''
from multiprocessing import Process
import time
def task(x):
    print("%s is runnin"%x)   #子進程打印輸出
    time.sleep(3)
    print('%s is done'%x)     #子進程打印輸出

if __name__ == '__main__':    #開進程要統一放到main方法的下面
    p=Process(target=task,args=('子進程',))
    p.start()
    print('')  #父進程的打印輸出
    
'''
注意點:
1.p=Process(target=task,args=('子進程',)) 
  這一步:只是在向操作系統發我要開啟一個子進程的信號(具體開子進程的操作是由操作系統來完成的)
  *所有這個過程中的時間也是不固定的
2.p.start():
  開啟一個子進程

運行過程分析:
    右鍵運行父類先運行起來(此時p.start()子類也已經在造了,但是會有時間延遲)-->print('主')-->
    然后依次運行子進程里面內容;子進程 is runnin\子進程 is done

'''

 

方式二:借助process類,自定義一個類(繼承Process),從而造一個對象

#方式二:借助process類,自定義一個類(繼承Process),從而造一個對象
from multiprocessing import Process
import time

class Myprocess(Process):
    #輔助理解,
    # def __init__(self,x):
    #     super().__init__()#保留原有Process類里面的方法
    #     self.name=x  #***如果要自定義傳參,self.name=x必須要放到super()._init_()下面
    # 
    def run(self):
        print("%s is running" % self.name)   #默認函數對象有name方法 ,結果為:Myprocess-1
        time.sleep(3)
        print('%s is done' % self.name)

if __name__ == '__main__':
    # p=Myprocess('子進程1',)     開啟init方式就可以自定義參數傳值
    p=Myprocess()    #實例化Myprocess類調用了類面的init方法,得到了一個對象p

    p1=Myprocess()

    p.start()    #p.run() 對象去調用了類里面的run方法,進而執行run里面的函數體代碼
    p1.start()
    print('')

 以上2中方式的對比分析:

方式二:子類只能運行同一個run里面輸出的方式(run名字是固定的,不能更改)

方式一:可以自定義多個task函數,並且寫不同的輸出內容,例如task1-->p1 task2-->p2...等等靈活性更高

 

 

父類、子類進程內存空間是彼此隔離的:

from multiprocessing import Process
import time

x=100
def task():
    global x
    x=11        #當子類已經建立成功時,子類里面對數據的變動,不會印象父類
    print(x)    #11
    print('done')
if __name__ == '__main__':
    p=Process(target=task)
    p.start()
    time.sleep(10) # 讓父進程在原地等待10,是為了等父類先建立好,用於驗證子類里面的變動不會影響父類的值
    print(x)    #打印時父類的,即全局的 100

 

 

 

 知識點三:僵屍進程、孤兒進程

  僵屍進程:(無害的)
  子進程運行結束后,會保留進程的ID號等信息,
  目的是為了父進程能查看子進程的狀態,以及回收僵屍狀態的子進程


  孤兒進程:(無害的)
  在子類沒有運行完的情況下,父類先行結束,這種情況下,當子進程結束時,
  狀態就叫做孤兒進程,當然也會被系統層面上的孤兒院回收

  有一種情況是有害的:
  如果父類,不停的在造子類,父類一直不死,此時PID會占用過多,導致內存也會占用很多
  這種情況是有害的

 

 

 知識點四:進程對象相關的屬性

1.PID接口查看

#查看PID應用:
# print(p.pid):外面直接查看子類pid
#os.getpid():在內部查看子類pid
#os.getpid():在外面查看父類的pid
#os.getppid():在里面查看父類的pid
import time
import os
from multiprocessing import Process

def task(x):

    print('%s is running'%os.getpid())   #子進程內查看自己pid的方式
    time.sleep(100)
    print('子類下查看父類的id:%s'%os.getppid())    #查看父類的pid
    time.sleep(100)
    print('%s is done'%x)

if __name__ == '__main__':
    p=Process(target=task,args=('子進程1',))
    p.start()
    print(p.pid,)   #父進程內查看子類pid的方式
    time.sleep(50)
    print('父類下查看父類自己的id:',os.getpid())
    print('')

 

2.join()

import time
from multiprocessing import Process

def task(name,n):
    print('%s is running'%name)
    time.sleep(n)
    print('%s is done'%name)

if __name__ == '__main__':
    p1=Process(target=task,args=("進程1",1)) #用時1s
    p2=Process(target=task,args=("進程2",2)) #用時1s
    p3=Process(target=task,args=("進程3",3)) #用時1s

    start_time=time.time()
    p1.start()
    # p1.join()  #如果是這種情況就是總共6s左右了
    p2.start()
    # p2.join()
    p3.start()
    # p3.join()

    # 讓父進程在原地等待,等子進程在運行完畢后,才執行下一行代碼()
    #注意:並不是串行,當第一秒在運行p1時,其實p2、p3也已經在運行,當1s后到p2時只需要再運行1s就到p3了,到p3也是一樣。
    p1.join()
    p2.join()
    p3.join()
    stop_time=time.time()     #3.2848567962646484總結
    print(stop_time-start_time)
    print('')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM