1. 程式人生 > 其它 >程序相關的內容

程序相關的內容

1. 程式碼建立程序

"""
建立程序的方式有哪些
    1.滑鼠雙擊桌面一個應用圖示
    2.程式碼建立
    
建立程序的本質:在記憶體中申請一塊記憶體空間用於執行相應的程式程式碼
"""

  1.2 建立程序的兩種方式

    第一種建立方式

from multiprocessing import Process
import time


def task(name):
    print('%s is running' % name)
    time.sleep(5)
    print('%s is over' % name)


if __name__ == '
__main__': p = Process(target=task, args=('dragon',)) # 建立一個程序物件 p.start() # 告訴作業系統建立一個新的程序 print('主程序') """ 強調:不同的作業系統建立程序的要求不一樣 在windows中建立程序是以匯入模組的方式進行 所以建立程序的程式碼必須寫在__main__子程式碼中 否則會直接報錯 因為在無限制建立程序 在linux和mac中建立程序是直接拷貝一份原始碼然後執行 不需要寫在__main__子程式碼中 """

 

 

    第二種建立方式

from
multiprocessing import Process import time class MyProcess(Process): def __init__(self, username): self.username = username super().__init__() def run(self): print('你好啊 小姐姐', self.username) time.sleep(3) print('get out!!!', self.username) if __name__
== '__main__': p = MyProcess('python') p.start() print('主程序')

 

 

2. 程序實現併發

服務端程式碼

import socket
from multiprocessing import Process

def get_server():
    server = socket.socket()
    server.bind(('127.0.0.1', 8080))
    server.listen(5)
    return server

# 將服務客戶端的程式碼封裝成函式(通訊程式碼)
def talk(sock):
    while True:
        data = sock.recv(1024)
        print(data.decode('utf8'))
        sock.send(data.upper())

if __name__ == '__main__':
    server = get_server()
    while True:
        sock, addr = server.accept()
        p = Process(target=talk, args=(sock, ))
        p.start()

 

客戶端程式碼

import socket


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

while True:
    client.send(b'python cat')
    data = client.recv(1024)
    print(data.decode('utf8'))

 

 

 

 

 

 

3. Join方法

# 讓主程序程式碼等待子程序程式碼執行完畢再執行
1.join方法的簡單使用
2.如何真正理解等待的過程

from multiprocessing import Process
import time


def task(name, n):
    print(f'{name} is running')
    time.sleep(n)
    print(f'{name} is over')


if __name__ == '__main__':
    p1 = Process(target=task, args=('cat', 1))
    p2 = Process(target=task, args=('dog', 2))
    p3 = Process(target=task, args=('chicken', 3))
    start_time = time.time()
    p1.start()
    p2.start()
    p3.start()
    p1.join()
    p2.join()
    p3.join()
    end_time = time.time() - start_time
    print('主程序', f'總耗時:{end_time}')
    
"""
需求:想讓p.start()之後的程式碼 等待子程序全部執行結束之後再列印
    1.sb(sweet baby)做法:直接sleep
        肯定不行 因為子程序執行的時間不可控
    2.join方法
        針對多個子程序的等待一定要理解!!!
"""

 

 

from multiprocessing import Process
import time


def task(name, n):
    print(f'{name} is running')
    time.sleep(n)
    print(f'{name} is over')


if __name__ == '__main__':
    p1 = Process(target=task, args=('cat', 1))
    p2 = Process(target=task, args=('dog', 2))
    p3 = Process(target=task, args=('chicken', 3))
    start_time = time.time()
    p1.start()
    p1.join()
    p2.start()
    p2.join()
    p3.start()
    p3.join()
    end_time = time.time() - start_time
    print('主程序', f'總耗時:{end_time}')

 

 

原因分析:因為Python程式碼是自上而下執行的
第一段程式碼是將所有程序都啟動後,然後使用join等待,所以三個程序都是在執行的
第二程式碼是啟動一個程序,然後join等待,所以啟動第一個程序的時候,第二個程序並沒有啟動,所以需要等待第一個程序結束才能啟動,第二段程式碼時間就先後對應的增長

 

4. 程序間資料預設隔離

# 記憶體可以看成是有很多個小隔間組成的 彼此不干擾
from multiprocessing import Process

money = 999


def task():
    global money  # 區域性修改全域性不可變型別
    money = 666


if __name__ == '__main__':
    p = Process(target=task)
    p.start()
    p.join()  # 確保子程序程式碼執行結束再列印money
    print(money)
 
"""預設隔離  但是可以通過一些技術打破"""

 

 

5. 程序物件屬性和方法

"""
程序號如何檢視
    windows:             tasklist結果集中PID
    mac:                    ps -ef
"""
1.檢視程序號的方法
  1.1.current_process函式
      from multiprocessing import Process, current_process
      current_process().pid
     # 獲取程序號的用處之一就是可以通過程式碼的方式管理程序
      windows              taskkill關鍵字
    mac/linux          kill關鍵字
  1.2.os模組
      os.getpid()  # 獲取當前程序的程序號
      os.getppid()  # 獲取當前程序的父程序號
2.殺死子程序
    terminate()
3.判斷子程序是否存活
    is_alive()

 

from multiprocessing import Process, current_process
import os

money = 999


def task():
    global money  # 區域性修改全域性不可變型別
    money = 666


if __name__ == '__main__':
    p = Process(target=task)
    p.start()
    print(current_process().pid)
    print(os.getpid())
    print(p.is_alive())
    p.join()
    print(money)

 

 

6. 殭屍程序與孤兒程序

殭屍程序
    # 為什麼主程序預設需要等待子程序結束才會結束
  所有的子程序在執行結束之後都會變成殭屍程序(死了沒死透)
  還保留著pid和一些執行過程的中的記錄便於主程序檢視(短時間儲存)
  這些資訊會被主程序回收(殭屍徹底死了)
      1.主程序正常結束
    2.呼叫join方法
  
孤兒程序
    # 子程序存活著 父程序意外死亡
  子程序會被作業系統自動接管(兒童福利院)

 

 

 

 

7. 守護程序

from multiprocessing import Process
import time


def task(name):
    print(f'{name}正常活著')
    time.sleep(3)
    print(f'{name}餓死了')

if __name__ == '__main__':
    p = Process(target=task, args=('貓主人',))
    p.start()
    print('Cat餓死了')

 

 

"""
守護即死活全部參考守護的物件
    物件死立刻死
"""
from multiprocessing import Process
import time


def task(name):
    print(f'{name}正常活著')
    time.sleep(3)
    print(f'{name}餓死了')

if __name__ == '__main__':
    p = Process(target=task, args=('貓主人',))
    # 必須寫在start前面
    p.daemon = True  # 將子程序設定為守護程序:主程序結束 子程序立刻結束
    p.start()
    print('Cat餓死了')

 

 

8. 互斥鎖

"""
講師:JasonJi    外號:雞哥
郵箱:[email protected]
微信:15618087189、18817628568(備註來源)
"""
import json
from multiprocessing import Process, Lock
import time
import random


# 查票
def search(name):
    with open(r'ticket_data.json', 'r', encoding='utf8') as f:
        data = json.load(f)
    print(f'{name}查詢當前餘票:%s' % data.get('ticket_num'))


# 買票
def buy(name):
    '''
    點選買票是需要再次查票的 因為期間其他人可能已經把票買走了
    '''
    # 1.查票
    with open(r'ticket_data.json', 'r', encoding='utf8') as f:
        data = json.load(f)
    time.sleep(random.randint(1, 3))
    # 2.判斷是否還有餘票
    if data.get('ticket_num') > 0:
        data['ticket_num'] -= 1
        with open(r'ticket_data.json', 'w', encoding='utf8') as f:
            json.dump(data, f)
        print(f'{name}搶票成功')
    else:
        print(f'{name}搶票失敗 沒有餘票了')


def run(name, mutex):
    search(name)
    # 只需要把買票環節變成序列即可
    mutex.acquire()  # 搶鎖
    buy(name)
    mutex.release()  # 放鎖


# 模擬多人同時搶票
if __name__ == '__main__':
    # 互斥鎖在主程序中產生一把 交給多個子程序用
    mutex = Lock()
    for i in range(1, 10):
        p = Process(target=run, args=('使用者:%s' % i, mutex))
        p.start()