python 進程的一些其他方法
OK通過上面兩篇的內容,對進程有了一個初步的認識 進程 就是一個方法,就跟面相對象,函數一樣,都是python中的方法,為了能夠
讓自己程序更有效率. 上兩篇就是告訴大家,進程的一個樣子,怎樣的一個書寫格式, 大家只要記住格式是什麽,會用就可以了, 進程的那些概念的東西,
大家可以沒事上百度,了解一下就可以了.
話不多說,接下來就是 進程 的一些使用方法
import os #這次我們倒入一個os模塊 待會查看一下進程id
from multiprocessing import Process
def f1():
print(‘子進程的pid‘,os.getpid()) #os.getpid()是獲取進程id 的
print(‘子進程的父進程的pid‘,os.getppid()) #os.getppid() 是獲取在子進程中父進程的進程id
#仔細看這兩個方法不一樣
print(‘aaa‘)
def f2():
print(‘bbb‘)
if __name__ == ‘__main__‘:
p1 = Process(target=f1,name=‘寶寶1‘)
p2 = Process(target=f2,)
p1.start()
p2.start()
print(p1.name) #查看進程傳參的屬性 也就是寶寶1 沒啥意思這個功能
print(‘子進程的pid‘,p1.pid) # 獲取子進程進程id
print(‘父進程的id‘,os.getpid()) #獲取父進程的id
最後打印完結果,你就會發現,所有的父進程是同一個id,,,所有子進程是同一個id, 這就說明子進程跟父進程是兩個id,不是一起的..稍微記住
from multiprocessing import Process
def f1():
print(‘子進程1號‘)
if __name__ == ‘__main__‘:
p = Process(target=f1,)
p.start()
print(p.is_alive()) #判斷子進程是否還活著,是否還在運行, 如果子進程還會運行會
反回一個True
p.terminate() #給操作系統發送一個結束進程的信號,然後操作系統幫他結束進程
print(p.is_alive()) #結束了進程,再查看的子進程是否還在運行,這時候就會返回False
既然不是一個id的,那麽是否是一個空間的呢?
from mulitiprocessing import Process
num = 100 #這是全局變量這個大家都知道吧 ,那麽接下來的幾行註釋就是打印結果
def f1():
global num
num = 3
print("子進程中的num") # 結果 3
print(num) #結果100 先說一下這裏是兩個一百,首先是先打印一個全局變量100
#等執行子進程的時候,子進程會把父進程的內容復制一遍,再次打印父進程內容
#所以就是兩個100
if __name__=="__main__":
p = Process(target = f1,)
p.start()
p.join()
print("主進程中的num",num) #結果100
最後結果就是 發現父進程是全局空間,子進程是局部空間 ,子進程再怎麽global改變全局變量,父進程裏的
num都沒變,父進程永遠都是一個空間,子進程是一個空間,那麽子進程再怎麽修改自己所在的空間裏的num,父進程
所在的空間的num都沒變, 這倆的空間跟全局,局部沒任何關系,這塊有點抽象,大家理解一下.
所以子進程跟父進程之間是空間隔離的.
守護進程:
import time
from multiprocessing import Process
def f1():
time.sleep(3)
print(‘xxxx‘)
def f2():
time.sleep(5)
print(‘普通子進程的代碼‘)
if __name__ == ‘__main__‘:
p = Process(target=f1,)
p.daemon = True #這個就是守護進程 ,p.daemon = True 將該進程設置為守護進程,必須寫在start之前,意思如果我的主進程代碼運行結束了,你這個子進程不管運行到什麽地方,都直接結束
p.start()
p2 = Process(target=f2,)
p2.start()
p2.join()
print(‘主進程結束‘)
這個最後打印完了就是先打印主進程"主進程結束" 再打印p2結果,p1不打印,這就是守護進程
開啟一個普通的子進程來驗證一下守護進程的結束只和主進程的代碼運行結束有關系,而整個程序的結束需要主進程和普通的子進程的代碼都運行結束才結束
守護進程會跟跟著父進程的代碼運行結束,就結束
但如果加上時間就不一樣了
如果p1時間比p2時間短 ,p2中間加一個阻隔的話join(),先不打印父進程,打印子進程,的話,那麽守護進程時間快
守護進程也就被打印了.所以而整個程序的結束需要主進程和普通的子進程的代碼都運行結束才結束
守護進程會跟跟著父進程的代碼運行結束,就結束
好好理解一下,打印一下,很簡單的.
互斥鎖,同步鎖,進程鎖 跟 數據共享
首先呀 互斥鎖,同步鎖,進程鎖 這三個鎖是同一個鎖,只不過是三種叫法 ,不必糾結 ,叫什們都行
import time
from multiprocessing import Process,Manager,Lock
def f1(m_d,l2): #OK 方法能先說一下,鎖是Lock, 數據共享是Manager
with l2: #with l2 是鎖的 一種簡寫 ,直接with鎖的對象,就把內容鎖住了
#l2.acquire() #這個就是鎖的原來的樣子了,先鎖住
tmp = m_d[‘num‘] # 中間這段代碼,是執行的內容,大家看一下咋回事就行,
tmp -= 1
time.sleep(0.1)
m_d[‘num‘] = tmp
# l2.release() #再開鎖 ,這就是鎖的寫法
if __name__ == ‘__main__‘:
m = Manager() #這個呢是數據共享,然後創建一個對象 m 隨便定義一個變量
l2 = Lock()
m_d = m.dict({‘num‘:100}) #然後傳共享參數,就跟小黃車一樣哈,雖然小黃車快黃了
p_list = []
for i in range(10): #創建10個進程
p = Process(target=f1,args=(m_d,l2)) 把共享屬性傳上去
p.start()
p_list.append(p) #為什們要加進一個列表裏面呢,是因為,我們要統一把10個進程
[pp.join() for pp in p_list] #都加上join(),一是內容需要,另一個就是,當我們創建很多個進程
print(m_d[‘num‘]) #的時候,操作順序不是我們能決定的,是操作系統來決定的,不加
#join的話,說不好他先操作那個進程,那不就亂了套了嗎,所以每個都加上join ,這樣10個進程都能按順序操作了.這是個很重要的一個知識點,一定要 記住了....
鎖呢是將10個進程一個一個的鎖住,打印的時候不亂套,要不然都進來的話數據內容就亂了
這塊跟join() 有點繞.join是讓操作系統 一個一個排序的進行進程操作, 而鎖呢是將進程內容給鎖起來,讓內容
一個一個操作,鎖是跟進程內容有關.
數據共享就是10個進程,都能用這個屬性
隊列:
from multiprocessing import Process,Queue
q = Queue(3) #創建一個隊列對象,隊列長度為3,先進先出
q.put(1) #輸入內容
# print(‘>>>>>‘,q.qsize()) #返回當前隊列的內容長度
print(q.full()) #查看隊列是否都滿了沒滿就返回False
q.put(2)
# print(‘>>>>>‘,q.qsize())
q.put(3)
print(q.full())
print(q.get()) #打印內容
print(q.get())
print(q.get())
print(‘是不是空了呀:‘,q.empty())
隊列大家打印一下,就可以了
for 循環
又來一個for循環,這個就是為了讓所有的所有的進程加join的,哈哈哈..看下數據共享跟鎖
那塊的那段話就知道了..
import time
from multiprocessing import Process
def f1():
time.sleep(0.5)
print(‘xxx‘)
if __name__ == ‘__main__‘:
p_list = []
#for循環創建子進程,並且完成主進程等待所有子進程執行結束,才繼續執行
for i in range(10):
p = Process(target=f1,)
p.start()
p_list.append(p)
p.join()
[pp.join() for pp in p_list]
print(‘主進程結束‘)
OK 東西有點多,不過都是一些方法而已大框沒變,裏邊加東西就可以了
大家好好記一下,練一下,記住多練就好了.
python 進程的一些其他方法