程式碼建立程序、join、程序和互斥鎖
阿新 • • 發佈:2022-04-19
-
程式碼建立程序
-
join方法
-
程序間資料預設隔離
-
程序物件相關屬性和方法
-
殭屍程序和孤兒程序
-
守護程序
-
互斥鎖
一、程式碼建立程序
""" 1.建立程序的方式 滑鼠雙擊桌面一個應用圖示 程式碼建立 建立程序的本質: 在記憶體中要一塊記憶體空間用來執行相應的程式程式碼 """ # multiprocessing 程序模組 # Process P是大寫 from multiprocessing import Process import time def task(name): print('%s is runing'% name) time.sleep(3) print('%s is over'% name) if __name__ == '__main__': p = Process(target=task, args= ('owen', )) p.start() print('主程序')
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('再會', self.username) if __name__ == '__main__': p = MyProcess('owen') p.start() print('主程序')
-
程序實現併發
# 它的實現就是將於客戶端通訊的程式碼封裝稱為一個函式, 之後來一個客戶就建立一個程序,專門服務 # 服務端 import socket from multiprocessing import Process def get_server(): server = socket.socket() server.bind(('127.0.0.1', 9999)) 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', 9999)) while True: client.send(b'hello') data = client.recv(1024) print(data.decode('utf8'))
二、join方法
# 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=('cuihua', 1))
p2 = Process(target=task, args=('xiongda', 2))
p3 = Process(target=task, args=('guangtouqiang', 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}')
# 主程序 總耗時:3.0834152698516846
如果想要p.start()之後的程式碼, 等待子程序全部執行結束之後再列印
1.直接sleep,但是這個方法肯定不可行,因為子程序執行時間不可控
2.join方法
針對多個子程序的等待
三、程序間資料預設隔離
# 我們可以把記憶體看成很對個小房間組成的, 一人一個互不干擾
from multiprocessing import Process
money = 100
def task():
global money # 區域性改全域性申明
money = 222
if __name__ == '__main__':
p = Process(target=task)
p.start()
p.join()
print(money)
# 同一臺計算機上面,程序和程序之間是資料隔離的
四、程序物件屬性和方法
"""
檢視程序號的方法:
windows: tasklist 結果集中PID
mac: ps -ef
"""
1.1、檢視程序號
courrent_process函式
from multiprocessing import Process, current_process
print(current_process().pid) # 13236
# 獲取程序號的目的就是可以通過程式碼的方式管理程序
windows系統: taskkill關鍵字
Mac/linux系統: kill關鍵字
1.2、os模組
os.getpid() # 獲取當前程序的程序號
os.getppid() # 獲取到當前程序的父程序號
2.殺死子程序
terminate() # 這個過程可能需要一點時間
3.判斷子程序是否存活
is_alive() # 返回True或者False
五、殭屍程序和孤兒程序
殭屍程序
所有的子程序在執行結束之後都會程式設計殭屍程序(死了沒死透)
因為還保留著pid和一些執行過程的中的記錄便於主程序檢視(只是短時間儲存)
等這些資訊被主程序回收,就徹底死了
1.主程序正常結束
2.呼叫join方法
# 殭屍程序是無害的
孤兒程序
# 子程序存在,但是父程序斃了
子程序會被作業系統自動接管
六、守護程序
"""
守護就是生死全靠守護的物件,對生守生, 對死守死
"""
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.daemon = True # 將子程序設定為守護程序,主程序結束,子程序立即結束
p.start()
print('皇上斃了')
# p.daemon = True 一定要放在p.start()上面
七、互斥鎖*
import json
from multiprocessing import Process
import time
import random
# 設定票數,一張
ticket_data.json : {"ticket_num": 1}
# 查票功能
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):
# 先查一下票數
with open(r'ticket_data.json', 'r', encoding='utf8') as f:
data = json.load(f)
time.sleep(random.randint(1, 3)) # 停留1~3秒
# 判斷
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):
search(name)
buy(name)
# 模擬多人同時
if __name__ == '__main__':
for i in range(1, 6):
p = Process(target=run, args=('使用者:%s' % i, ))
p.start()
使用者:2查詢餘額為:2
使用者:1查詢餘額為:2
使用者:3查詢餘額為:2
使用者:5查詢餘額為:2
使用者:4查詢餘額為:2
使用者:4搶票成功使用者:5搶票成功
使用者:2搶票成功
使用者:1搶票成功
使用者:3搶票成功
# 結果很明顯,是錯亂的,而且都5個人買一張都成功了
"""
在多個程序操作同一個資料的時候會造成資料的錯亂, 所以我們需要增加一個加鎖處理(互斥鎖)
將併發變成序列, 效率低了,但安全性高了
互斥鎖並不能輕易使用, 容易造成死鎖現象
互斥鎖旨在處理資料的部分加鎖, 不能什麼地方都加
"""
# 增加互斥鎖
from multiprocessing import Process, Lock
mutex = Lock()
mutex.acquire() # 上鎖
mutex.release() # 解鎖
# 將買票封裝成函式
def run(name,mutex):
search(name)
mutex.acquire() # 上鎖
buy(name)
mutex.release() # 解鎖
# 模擬多人同時
if __name__ == '__main__':
mutex = Lock()
for i in range(1, 6):
p = Process(target=run, args=('使用者:%s' % i, mutex))
p.start()
使用者:1查詢餘額為:2
使用者:2查詢餘額為:2
使用者:3查詢餘額為:2
使用者:4查詢餘額為:2
使用者:5查詢餘額為:2
使用者:1搶票成功
使用者:2搶票成功
使用者:3搶票失敗,票已經沒了
使用者:4搶票失敗,票已經沒了
使用者:5搶票失敗,票已經沒了
"""
行鎖: 針對行數加鎖, 同一時間只能一個人操作
表鎖: 針對表資料加鎖, 同一時間只能一個人操作
"""