多進程,守護進程,鎖

多進程,鎖

一:多進程html

import os
import time
from multiprocessing import Process
def func(args,args2):  print(args,args2)#打印參數  time.sleep(3) print('子進程 :', os.getpid()) #查看子進程進程號  print('子進程的父進程 :', os.getppid())#查看子進程的父進程,多了一個p  print(12345) if __name__ == '__main__':  p = Process(target=func,args=('參數','參數2')) # 註冊  # p是一個進程對象,尚未啓動進程  p.start() # 開啓了一個子進程  print('*'*10) print('父進程 :',os.getpid()) # 查看當前進程的進程號  print('父進程的父進程 :',os.getppid()) # 查看當前進程的父進程 # 進程的生命週期  # 主進程  # 子進程  # 開啓了子進程的主進程 :  # 主進程本身的代碼若是長,等待本身的代碼執行結束,  # 子進程的執行時間長,主進程會在主進程代碼執行完畢以後等待子進程執行完畢以後 主進程才結束

打印結果: 先打印主進程,而後打印子進程。主進程結束執行子進程。python

**********
父進程 : 3832
父進程的父進程 : 2556
參數 參數2
子進程 : 5416
子進程的父進程 : 3832
12345json

 

二:多進程的中的幾個方法(多進程便可指子進程,父進程這兩個進程,也可指多個實例化兩個進程)安全

import time
from multiprocessing import Process

def func(arg1,arg2):  print('*'*arg1) time.sleep(5) print('*'*arg2) if __name__ == '__main__':  p = Process(target=func,args=(10,20)) p.start() print('hahahaha') # p.join() # 是感知一個子進程的結束,將異步的程序改成同步  print('====== : 運行完了')

這樣就是正常打印,主進程執行完畢執行子進程網絡

hahahaha
====== : 運行完了
**********
********************app

 

若是加上join以後,是感知一個子進程的結束,將異步的程序改成同步。也就是等待子進程結束後主進程關閉dom

打印結果:異步

hahahaha
**********
********************
====== : 運行完了socket

若是子進程是一個while循環的死循環,那麼主進程就一直不會關閉。函數

import os
import time
from multiprocessing import Process

def func():  while True:  print('子進程開始') time.sleep(1) print('***我還在運行') if __name__ == '__main__':  p = Process(target=func) p.daemon = True p.start() p.join() print('程序結束')

打印結果:

子進程開始
***我還在運行
子進程開始
***我還在運行

老是在子進程這裏循環

 

3小總結:

process小知識:

Process([group [, target [, name [, args [, kwargs]]]]]),由該類實例化獲得的對象, 表示一個子進程中的任務(還沒有啓動) 強調: 1. 須要使用關鍵字的方式來指定參數 2. args指定的爲傳給target函數的位置參數,是一個元組形式,必須有逗號 參數介紹: 1 group參數未使用,值始終爲None 2 target表示調用對象,即子進程要執行的任務 3 args表示調用對象的位置參數元組,args=(1,2,'egon',) 4 kwargs表示調用對象的字典,kwargs={'name':'egon','age':18} 5 name爲子進程的名稱

 

進程常見關鍵字

1 p.start():啓動進程,並調用該子進程中的p.run() 
2 p.run():進程啓動時運行的方法,正是它去調用target指定的函數,咱們自定義類的類中必定要實現該方法 3 p.terminate():強制終止進程p,不會進行任何清理操做,若是p建立了子進程,該子進程就成了殭屍進程, 使用該方法須要特別當心這種狀況。若是p還保存了一個鎖那麼也將不會被釋放,進而致使死鎖 4 p.is_alive():若是p仍然運行,返回True 5 p.join([timeout]):主線程等待p終止(強調:是主線程處於等的狀態,而p是處於運行的狀態)。 timeout是可選的超時時間,須要強調的是,p.join只能join住start開啓的進程,而不能join住run開啓的進程

 

process模塊裏面屬性:

1 p.daemon:默認值爲False,若是設爲True,表明p爲後臺運行的守護進程,當p的父進程終止時,p也隨之終止,
而且設定爲True後,p不能建立本身的新進程,必須在p.start()以前設置
2 p.name:進程的名稱 3 p.pid:進程的pid 4 p.exitcode:進程在運行時爲None、若是爲–N,表示被信號N結束(瞭解便可) 5 p.authkey:進程的身份驗證鍵,默認是由os.urandom()隨機生成的32字符的字符串。 這個鍵的用途是爲涉及網絡鏈接的底層進程間通訊提供安全性, 這類鏈接只有在具備相同的身份驗證鍵時才能成功(瞭解便可)

 

4開啓多個子進程

import os
import time
from multiprocessing import Process

def func(filename,content):  with open(filename,'w') as f:  f.write(content*10*'*') if __name__ == '__main__':  p_lst = [] for i in range(10):  p = Process(target=func,args=('info%s'%i,i)) p_lst.append(p) p.start() for p in p_lst:p.join() # 以前的全部進程必須在這裏都執行完才能執行下面的代碼  print([i for i in os.walk(r'F:\python10期\day37\day37')]) # 同步 0.1 * 500 = 50 # 異步 500 0.1 = 0.1 # 多進程寫文件 # 首先往文件夾中寫文件 # 向用戶展現寫入文件以後文件夾中全部的文件名

解析:他會在全部進程結束以後才能完成下面的print。

 

5 開啓多個子進程的第二種方式:

import os
from multiprocessing import Process

class MyProcess(Process):  def __init__(self,arg1,arg2):  super().__init__() self.arg1 = arg1 self.arg2 = arg2  def run(self):  print(self.pid) print(self.name) print(self.arg1) print(self.arg2) if __name__ == '__main__':  p1 = MyProcess(1,2) p1.start() p2 = MyProcess(3,4) p2.start() # 自定義類 繼承Process類 # 必須實現一個run方法,run方法中是在子進程中執行的代碼

這種方式須要第必定義一個類,讓他繼承process,第二種是傳參,須要初始化,而後是定義一個run方法,由於定義run方法以後才能執行start,而後在實例化二個對象。分別執行。

打印結果:

6356
MyProcess-1
1
2
3136
MyProcess-2
3
4

由於此進程是異步,因此process1和process2不肯定誰最早打印,隨機。super是執行process全部方法。

 

6 多進程中的數據隔離原則

# 進程 與 進程之間
import os
from multiprocessing import Process

def func():
    global n   # 聲明瞭一個全局變量
    n = 0       # 從新定義了一個n
    print('pid : %s'%os.getpid(),n)

if __name__ == '__main__':
    n = 100
    p = Process(target=func)
    p.start()
    p.join()
    print(os.getpid(),n)

打印結果:

pid : 6004 0
1240 100

注意:兩個進程之間隔離,彼此不受影響。

 

守護進程:                                                                                 

# 子進程 -- > 守護進程

import time
from multiprocessing import Process

def func():
    while True:
        time.sleep(0.2)
        print('我還活着')

def func2():
    print('in func2 start')
    time.sleep(8)
    print('in func2 finished')

if __name__ == '__main__':
    p = Process(target=func)
    p.daemon = True   # 設置子進程爲守護進程
    p.start()
    p2 = Process(target=func2)
    p2.start()
    p2.terminate()     # 結束一個子進程
    time.sleep(1)
    print(p2.is_alive())  # 檢驗一個進程是否還活着
    print(p2.name)
    i = 0
    while i<5:
        print('我是socket server')
        time.sleep(1)
        i+=1

 

買火車票涉及的鎖問題:

# 鎖

# 火車票
import json
import time
from multiprocessing import Process
from multiprocessing import Lock

# def show(i):
#     with open('ticket') as f:
#         dic = json.load(f)
#     print('餘票: %s'%dic['ticket'])

def buy_ticket(i,lock):
    lock.acquire() #拿鑰匙進門
    with open('ticket') as f:
        dic = json.load(f)
        time.sleep(0.1)
    if dic['ticket'] > 0 :
        dic['ticket'] -= 1
        print('\033[32m%s買到票了\033[0m'%i)
    else:
        print('\033[31m%s沒買到票\033[0m'%i)
    time.sleep(0.1)
    with open('ticket','w') as f:
        json.dump(dic,f)
    lock.release()      # 還鑰匙

if __name__ == '__main__':
    # for i in range(10):
    #     p = Process(target=show,args=(i,))
    #     p.start()
    lock = Lock()
    for i in range(10):
        p = Process(target=buy_ticket, args=(i,lock))
        p.start()

lock.release() 還鑰匙         lock.acquire() 拿鑰匙進門

在此以前要引用鎖這個模塊,from multiprocessing import Lock

相關文章
相關標籤/搜索