🌌 專注Golang,Python語言,云原生,人工智能領域得博主;
💜 過去經歷的意義在于引導你,而非定義你;
📢 歡迎點贊 👍 收藏 ?留言!

Python行程和執行緒的使用
- 01-多行程的使用
- 02-獲取行程編號
- 03-行程傳參
- 04-行程不共享全域變數
- 05-主行程會會等待子行程結束再結束
- 06-讓子行程隨著主行程的結束而結束
- 07-多執行緒的使用
- 08-執行緒傳參
- 09-執行緒的執行是無序的
- 10-主執行緒會等待子執行緒結束在結束
- 11-讓子執行緒隨著主執行緒的結束而結束
- 12-同一個行程中的執行緒共享全域變數
- 13-執行緒共享全域變數的問題
01-多行程的使用
# 1. 導包
import multiprocessing
import time
# 2.1 定義任務函式 唱歌
def sing():
# 回圈只執行了 5 次,在一個時間片內就執行結束了
for i in range(5):
print('正在唱歌.....')
# 執行一次唱歌之后,代碼實作,手動的失去 CPU,切換任務, time.sleep()
time.sleep(0.1) # 讓程式休眠 0.1秒, 行程會進入阻塞態,失去 CPU
# 2.2 跳舞
def dance():
for i in range(5):
print('正在跳舞....')
time.sleep(0.1)
if __name__ == '__main__':
# 2. 創建行程物件
# target 引數指定行程執行的任務,引數需要是函式, 并且是函式名, 不能加括號,
process_1 = multiprocessing.Process(target=sing) # 創建行程,分配任務,sing
process_2 = multiprocessing.Process(target=dance) # 創建行程,分配任務,sing
# 3. 啟動的行程, 相當于是讓行程處于就緒態,等待 CPU 分配時間
process_1.start()
process_2.start()
02-獲取行程編號
# 1. 導包
import multiprocessing
import time
import os
# 2.1 定義任務函式 唱歌
def sing():
# 回圈只執行了 5 次,在一個時間片內就執行結束了
print('sing:', multiprocessing.current_process(), multiprocessing.current_process().pid) # process-1
# os.getpid 獲取當前行程的 id os.getppid() 獲取父行程的 id
print(f'sing, pid {os.getpid()}, ppid{os.getppid()}')
for i in range(5):
print('正在唱歌.....')
# 執行一次唱歌之后,代碼實作,手動的失去 CPU,切換任務, time.sleep()
time.sleep(0.1) # 讓程式休眠 0.1秒, 行程會進入阻塞態,失去 CPU
os.kill(os.getpid(), 9) # 殺死當前行程,
# 2.2 跳舞
def dance():
print('dance:', multiprocessing.current_process(), multiprocessing.current_process().pid) # process-2
print(f'dance, pid {os.getpid()}, ppid{os.getppid()}')
for i in range(5):
print('正在跳舞....')
time.sleep(0.1)
if __name__ == '__main__':
# 程式啟動,默認會有一個行程,主行程
# 2. 創建行程物件
# target 引數指定行程執行的任務,引數需要是函式, 并且是函式名, 不能加括號,
# 行程物件.name 獲取行程的名字, 行程物件.pid 能夠獲取行程物件的行程 id
# multiprocessing.current_process() 獲取當前的行程物件
print('main:', multiprocessing.current_process(), multiprocessing.current_process().pid) # 主行程執行
print(f'main, pid {os.getpid()}, ppid{os.getppid()}')
process_1 = multiprocessing.Process(target=sing) # 創建行程,分配任務,sing
process_2 = multiprocessing.Process(target=dance) # 創建行程,分配任務,sing
# 3. 啟動的行程, 相當于是讓行程處于就緒態,等待 CPU 分配時間
process_1.start()
process_2.start()
03-行程傳參
# 1. 導包
import multiprocessing
import time
# 2.1 定義任務函式 唱歌
def sing(singer, song):
# 回圈只執行了 5 次,在一個時間片內就執行結束了
for i in range(5):
print(f'{singer}正在唱{song}.....')
# 執行一次唱歌之后,代碼實作,手動的失去 CPU,切換任務, time.sleep()
time.sleep(0.1) # 讓程式休眠 0.1秒, 行程會進入阻塞態,失去 CPU
# 2.2 跳舞
def dance(dancer, name):
for i in range(5):
print(f'{dancer}正在跳{name}_____________')
time.sleep(0.1)
if __name__ == '__main__':
# 2. 創建行程物件
# 由于行程執行的任務函式,sing 和 dance 都有形參,所有在創建物件的時候需要傳遞實參
# 方式一, args 形參, 實參值需要是元組型別,
process_1 = multiprocessing.Process(target=sing, args=('毛不易', '消愁')) # 創建行程,分配任務,sing
# 方式二, kwargs 形參, 實參值需要是字典,字典的 key 是任務函式的形參名,
process_2 = multiprocessing.Process(target=dance,
kwargs={'dancer': '羅老師', 'name': '精武門'}) # 創建行程,分配任務,sing
# 3. 啟動的行程, 相當于是讓行程處于就緒態,等待 CPU 分配時間
process_1.start()
process_2.start()
04-行程不共享全域變數
# 1. 導包
import multiprocessing
import time
# 定義全域變數
g_list = []
# 2.1 定義行程執行的任務函式
def write_data():
for i in range(5):
g_list.append(i)
print('添加資料成功', i)
# 代碼執行到此,代表 5 個資料添加完成
print(f"write_data: {g_list}")
def read_data():
print(f"read: {g_list}")
if __name__ == '__main__':
# g_list = []
# 2. 創建行程物件
write_process = multiprocessing.Process(target=write_data)
read_process = multiprocessing.Process(target=read_data)
# 3. 啟動行程
write_process.start()
write_process.join() # 1. 主行程阻塞等待 2. 等等待write_process 執行完成
read_process.start()
# 需求: 主行程在最后列印 g_list 值
# 解決方案: 使用 行程物件.join() 方法, 阻塞等待行程執行完成
# 1. 誰阻塞等待, 這行代碼寫在哪,哪個行程就阻塞等待
# 2. 等待誰執行完成, 哪個物件呼叫這個方法,就是等待哪個物件執行完成
print(f"main: {g_list}")
05-主行程會會等待子行程結束再結束
import multiprocessing
import time
def func():
for i in range(5):
print('子行程', i)
time.sleep(0.5) # 子行程至少需要 2.5 秒才能結束
print('子行程代碼結束,即活干完了')
if __name__ == '__main__':
sub_process = multiprocessing.Process(target=func)
sub_process.start()
time.sleep(1) # 主行程至少需要 1 秒結束
print('主行程的代碼結束, 即活干完了') # 主行程結束,程式就結束了
06-讓子行程隨著主行程的結束而結束
import multiprocessing
import time
import sys
def func():
for i in range(5):
print('子行程', i)
time.sleep(0.5) # 子行程至少需要 2.5 秒才能結束
print('子行程代碼結束,即活干完了')
if __name__ == '__main__':
sub_process = multiprocessing.Process(target=func)
# 方案二 將子行程物件設定為 daemon 行程
# sub_process.daemon = True # 修改物件的屬性
sub_process.start()
time.sleep(1) # 主行程至少需要 1 秒結束
print('主行程的代碼結束, 即活干完了') # 主行程結束,程式就結束了
# 主行程結束了,想讓子行程一塊結束,
# 方案一
# sub_process.terminate() # 終止子行程的執行
# exit() # 讓行程退出
sys.exit()
07-多執行緒的使用
# 1. 導包
import threading
import time
# 2.1 定義任務函式 唱歌
def sing():
print("sing", threading.current_thread().name)
# 回圈只執行了 5 次,在一個時間片內就執行結束了
for i in range(5):
print('正在唱歌.....')
time.sleep(0.1) # 讓程式休眠 0.1秒, 行程會進入阻塞態,失去 CPU
# 2.2 跳舞
def dance():
print("dance", threading.current_thread().name)
for i in range(5):
print('正在跳舞....')
time.sleep(0.1)
if __name__ == '__main__':
# 2. 創建執行緒物件
print("main", threading.current_thread().name)
thread_1 = threading.Thread(target=sing)
thread_2 = threading.Thread(target=dance)
# 3. 啟動執行緒
thread_1.start()
thread_2.start()
08-執行緒傳參
# 1. 導包
import threading
import time
# 2.1 定義任務函式 唱歌
def sing(singer, song):
print("sing", threading.current_thread().name)
# 回圈只執行了 5 次,在一個時間片內就執行結束了
for i in range(5):
print(f'{singer}正在唱歌 {song}.....')
time.sleep(0.1) # 讓程式休眠 0.1秒, 行程會進入阻塞態,失去 CPU
# 2.2 跳舞
def dance(dancer, name):
print("dance", threading.current_thread().name)
for i in range(5):
print(f'{dancer}正在跳舞{name}....')
time.sleep(0.1)
if __name__ == '__main__':
# 2. 創建執行緒物件
print("main", threading.current_thread().name)
thread_1 = threading.Thread(target=sing, kwargs={'singer': '毛不易', 'song': '消愁'})
thread_2 = threading.Thread(target=dance, args=('羅老師', '精武門'))
# 3. 啟動執行緒
thread_1.start()
thread_2.start()
09-執行緒的執行是無序的
# 1. 導包
import threading
import time
# 2.1 定義執行緒執行的任務函式
def func():
time.sleep(1)
print(threading.current_thread().name)
if __name__ == '__main__':
# 回圈創建執行緒
for i in range(10):
# 2. 創建執行緒物件
sub_process = threading.Thread(target=func)
# 3. 啟動執行緒
sub_process.start()
10-主執行緒會等待子執行緒結束在結束
import threading
import time
def func():
for i in range(5):
print(threading.current_thread().name, i)
time.sleep(0.5) # 2.5 s
print('子執行緒的任務結束')
if __name__ == '__main__':
sub_thread = threading.Thread(target=func)
sub_thread.start()
time.sleep(1)
print('主執行緒的任務結束了')
11-讓子執行緒隨著主執行緒的結束而結束
import threading
import time
def func():
for i in range(5):
print(threading.current_thread().name, i)
time.sleep(0.5) # 2.5 s
print('子執行緒的任務結束')
if __name__ == '__main__':
# 想讓子執行緒隨著主執行緒結束而結束,可以將子執行緒設定為 daemon 執行緒
# 方法一, 在創建物件的時候,設定
# sub_thread = threading.Thread(target=func, daemon=True)
sub_thread = threading.Thread(target=func)
# 方法二
# sub_thread.daemon = True
sub_thread.setDaemon(True)
sub_thread.start()
time.sleep(1)
print('主執行緒的任務結束了')
12-同一個行程中的執行緒共享全域變數
import threading
g_list = []
def write():
for i in range(5):
g_list.append(i)
print('添加資料', i)
print('write:', g_list)
def read():
print('read:', g_list)
if __name__ == '__main__':
write_thread = threading.Thread(target=write)
read_thread = threading.Thread(target=read)
write_thread.start()
read_thread.start()
print('main:', g_list)
13-執行緒共享全域變數的問題
import threading
# 定義全域變數
g_num = 0
# 定義任務函式
def func():
global g_num # 宣告使用全域變數
for i in range(1000000):
g_num += 1
# 當子執行緒中的代碼執行到此, 代表子執行緒的 100萬次加 1 完成
print(threading.current_thread().name, g_num)
if __name__ == '__main__':
sub_thread1 = threading.Thread(target=func)
sub_thread2 = threading.Thread(target=func)
sub_thread1.start()
sub_thread2.start()
sub_thread1.join() # 等待執行緒 1 執行結束
sub_thread2.join() # 等待執行緒 2 執行結束
print('main:', g_num)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/387769.html
標籤:AI
