14. 執行緒
(1) 建立一個執行緒
程式的執行有一個主執行緒. 在主執行緒建立另一個執行緒並啟動它, 整個程式因此有2個執行緒"同時"執行. 所謂的"同時", 是大家分享CPU時間, 交錯執行.
import threading
import time
#-----------------------------
# 執行緒函式
#-----------------------------
def my_function():
print("開始執行緒")
for i in range(10):
print(i)
time.sleep(1) #暫停1秒
print("結束執行緒")
#-----------------------------
# 主程式
#-----------------------------
print("<<主執行緒開始>>")
# 建立一個執行緒物件
my_thread = threading.Thread(target=my_function)
# 啟動執行緒
my_thread.start()
# 等待執行緒完成
my_thread.join()
print("<<主執行緒完成>>")
執行結果:
<<主執行緒開始>>
開始執行緒
0
1
2
3
4
5
6
7
8
9
結束執行緒
<<主執行緒完成>>
(2) 多個執行緒之間有自己的區域變數
執行緒函式內的變數是由每個執行緒維持自己的一份, 與其他執行緒不互相影響.
import threading
import time
#-----------------------------
# 執行緒函式
#-----------------------------
def my_function():
print("開始執行緒")
for i in range(10):
print(i)
time.sleep(1) #暫停1秒
print(f"結束執行緒")
#-----------------------------
# 主程式
#-----------------------------
print("<<主執行緒開始>>")
# 建立一個執行緒物件
my_thread1 = threading.Thread(target=my_function)
my_thread2 = threading.Thread(target=my_function)
# 啟動執行緒
my_thread1.start()
my_thread2.start()
# 等待執行緒完成
my_thread1.join()
my_thread2.join()
print("<<主執行緒完成>>")
執行結果:
<<主執行緒開始>>
開始執行緒
0
開始執行緒
0
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
結束執行緒
結束執行緒
<<主執行緒完成>>
(3) 傳參數給執行緒
import threading
import time
#-----------------------------
# 執行緒函式
#-----------------------------
def my_function(name):
print(f"開始執行緒{name}")
for i in range(10):
print(f'{name}:{i}')
time.sleep(1) #暫停1秒
print(f"結束執行緒{name}")
#-----------------------------
# 主程式
#-----------------------------
print("<<主執行緒開始>>")
# 建立一個執行緒物件
my_thread1 = threading.Thread(target=my_function, args=('Tom',))
my_thread2 = threading.Thread(target=my_function, args=('Mary',))
# 啟動執行緒
my_thread1.start()
my_thread2.start()
# 等待執行緒完成
my_thread1.join()
my_thread2.join()
print("<<主執行緒完成>>")
執行結果:
<<主執行緒開始>>
開始執行緒Tom
Tom:0
開始執行緒Mary
Mary:0
Tom:1
Mary:1
Tom:2
Mary:2
Mary:3
Tom:3
Tom:4
Mary:4
Tom:5
Mary:5
Tom:6
Mary:6
Tom:7
Mary:7
Tom:8
Mary:8
Tom:9
Mary:9
結束執行緒Tom
結束執行緒Mary
<<主執行緒完成>>
(4) 執行緒之間共用廣域變數
import threading
import time
# 建立一個鎖
lock = threading.Lock()
# 廣域變數
counter=0
#-----------------------------
# 執行緒函式
#-----------------------------
def my_function(name):
global counter
print(f"開始執行緒{name}")
for i in range(10):
with lock:
counter+=1
print(f'{name}:{counter}')
time.sleep(1) #暫停1秒
print(f"結束執行緒{name}")
#-----------------------------
# 主程式
#-----------------------------
print("<<主執行緒開始>>")
# 建立一個執行緒物件
my_thread1 = threading.Thread(target=my_function, args=('Tom',))
my_thread2 = threading.Thread(target=my_function, args=('Mary',))
# 啟動執行緒
my_thread1.start()
my_thread2.start()
# 等待執行緒完成
my_thread1.join()
my_thread2.join()
print("<<主執行緒完成>>")
執行結果:
<<主執行緒開始>>
開始執行緒Tom
Tom:1
開始執行緒Mary
Mary:2
Tom:3
Mary:4
Mary:5
Tom:6
Mary:7
Tom:8
Tom:9
Mary:10
Mary:11
Tom:12
Mary:13
Tom:14
Tom:15
Mary:16
Mary:17
Tom:18
Mary:19
Tom:20
結束執行緒Mary
結束執行緒Tom
<<主執行緒完成>>
(5) 執行緒與閉包
import threading
import time
import random
#--------------------------
# 取得counter()物件的位址
#--------------------------
def make_counter():
cnt=0
def counter():
nonlocal cnt
cnt+=1
return cnt
return counter
#--------------------------
# 執行緒內容的函式
#--------------------------
def my_function(name, counter):
for i in range(10):
print(f'{name}->{counter()}')
time.sleep(random.randint(1,2))
#------------------
# 產生一個閉包
#------------------
counter=make_counter()
#------------------
# 產生2個執行緒
#------------------
my_thread1 = threading.Thread(target=my_function, args=('tom', counter))
my_thread2 = threading.Thread(target=my_function, args=('mary', counter))
#------------------
# 啟動執行緒
#------------------
my_thread1.start()
my_thread2.start()
執行結果:
tom->1
mary->2
tom->3
mary->4
tom->5
mary->6
mary->7
tom->8
mary->9
tom->10
tom->11
mary->12
mary->13
tom->14
tom->15
mary->16
tom->17
mary->18
tom->19
mary->20
Last updated