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 東西有點多,不過都是一些方法而已大框沒變,裡邊加東西就可以了
大家好好記一下,練一下,記住多練就好了.