1. 程式人生 > >python筆記(程序編寫方式,join,隔離,守護程序,程序鎖)

python筆記(程序編寫方式,join,隔離,守護程序,程序鎖)

一、程序的幾個方法

from multiprocessing import Process
import os
import time
def func(arg):
    print(arg)
    print(12345)
    time.sleep(1)
    print('子程序:',os.getpid())
    print('子程序的父程序')   #檢視子程序的父程序
    print(54321)
if __name__ == '__main__':
    p = Process(target=func,args=('引數',))    #註冊    p是一個程序物件,還沒有啟動程序
    p.start()                  #開啟一個子程序
    print('*'*2)
    print('父程序:',os.getpid())
    print('父程序的父程序:',os.getppid()) #檢視父程序的父程序

輸出結果:

**
父程序: 11508
父程序的父程序: 14160
子程序中的列印不顯示

二、程序的生命週期
1、主程序
2、 子程序
3、開啟了子程序的主程序:
(1)自己的程式碼如果長,等待自己的程式碼執行結束
(2)子程序的執行時間長,主程序會在主程序程式碼執行完畢後等待子程序執行完畢後,主程序才結束
三、join方法:

join
import time
from multiprocessing import Process

def func(r1,r2):
    print('*'*r1)
    time.sleep(2)
    print('*'*r2)

if __name__ == '__main__':
    p = Process(target=func,args=(10,20))
    p.start()
    p.join()    #是感知一個程序的結束
    print('end')

輸出結果:

子程序中的列印不顯示
end

四、程序編寫的兩種方式:
1、多個程序第一種方式

import time
from multiprocessing import Process

def func(r1,r2):
    print('*'*r1)
    time.sleep(2)
    print('*'*r2)

if __name__ == '__main__':
    p_list = []
    for i in range(10):
        p = Process(target=func,args=(10*i,20*i))
        p_list.append(p)
        p.start()
    [p.join() for p in p_list]
    print('end')

輸出結果:

當所有程式執行完
end

2、多個程序第二種方式

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):                 #必須實現一個run方法,run方法是在子程序中執行的程式碼
        print(os.getppid())
        print(self.name)           #程序名
        print(self.pid)            #程序號
        print(self.arg1)
if __name__ == '__main__':
        print('主:', os.getppid())
        p1 = MyProcess(1,2)
        p1.start()                    #自動呼叫run法
        p2 = MyProcess(3,4)
        p2.start()

@自定義類 繼承Process類
輸出結果:

主: 11388
子程序中的列印不顯示

五、多程序之間隔離問題

from multiprocessing import Process
import os
import time
def func():
    global n
    n = 0
    print('pid:%s'%os.getpid(),n)
    time.sleep(5)
if __name__ == '__main__':
    n = 100
    p = Process(target=func)
    p.start()
    # p.join()
    print(os.getppid(),n)

輸出結果:

11388 0
xxxx 100

六、守護程序(子程序->守護程序)

import time
from multiprocessing import Process
def func():
    while True:
        time.sleep(0.5)
        print("I'm fine" )
def func2():
    print('func2')
    time.sleep(8)
    print('in func2 finsh')

if __name__ == '__main__':
    p = Process(target=func)
    p.daemon = True            #設定子程序為守護程序
    p.start()
    p2 = Process(target=func2)
    p2.start()
    p2.terminate()              #結束一個子程序
    print(p.is_alive())
    time.sleep(3)
    print(p2.is_alive())        #檢測一個程序是否還活著

(1)程序會隨著主程序的程式碼執行完畢而結束
(2)結束一個程序不是在執行方法之後立即生效,需要一個作業系統響應的過程

七、程序鎖
火車票問題

import json
import time
from multiprocessing import Process,Lock
def buy_ticket(i):
    lock.acquire()  #拿鑰匙進門
    with open('ticket') as f:
        dic = json.load(f)
        time.sleep(0.5)
    if dic['ticket'] > 0:
        dic['ticket'] -= 1
        print('%s買到了'%i)
    else:
        print('%s沒買到'%i)
    time.sleep(0.5)
    with open('ticket','w') as f:
        json.dump(dic,f)
    lock.release()  #還鑰匙

def show():
    with open('ticket',encoding='utf-8') as f:
        ret = json.load(f)
    print('餘票%s'%ret['ticket'])
if __name__ == '__main__':
    for i in range(10):
        p = Process(target=show)
        p.start()
    lock = Lock()
    for i in range(10):
        p = Process(target=buy_ticket,args=(i,))
        p.start()

八、複習
1、多程序程式碼(socket)
server端:

import socket
from multiprocessing import Process

def servers(conn):
    reg = '你好'.encode('utf-8')
    conn.send(reg)
    msg = conn.recv(1024).decode('utf-8')
    print(msg)
    conn.close()


if __name__ == '__main__':
    sk = socket.socket()
    sk.bind(('127.0.0.1', 8080))
    sk.listen(5)
    while True:
        conn, addr = sk.accept()
        p = Process(target=servers, args=(conn,))
        p.start()
    sk.close()

client端:(可連線多個使用者)

import socket

sk = socket.socket()
sk.connect(('127.0.0.1',8080))

ret = sk.recv(1024).decode('utf-8')
print(ret)
msg = input('>>').encode('utf-8')
sk.send(msg)

sk.close()

2、方法
(1)程序物件.start()開啟一個子程序
(2)程序物件.join()感知一個程序的結束
(3)程序物件.terminate()結束一個子程序
(4)程序物件.is_alive()檢視某個程序是否還在執行
3、屬性
(1) 程序物件.name程序名
(2)程序物件.pid程序號
(3)程序物件.daemo n值為True的時候,表示新的子程序是一個守護進守護程序,隨著主程序程式碼的執行結束而結束,一定在start之成設定。