【一】threading模組開啟執行緒的兩種方式
【1】直接呼叫Thread
from threading import Thread
import time
def task(name):
print(f'{name} is starting')
time.sleep(3)
print(f'{name} is ending')
def main():
t = Thread(target=task, args=("drake",))
# 建立執行緒的開銷非常小,幾乎程式碼執行的一瞬間執行緒就已經建立了
t.start()
if __name__ == '__main__':
main()
# drake is starting
# drake is ending
【2】繼承Thread父類
from threading import Thread
import time
class MyThread(Thread):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
print(f'{self.name} is starting')
time.sleep(3)
print(f'{self.name} is ending')
def main():
t1 = MyThread('dream')
t2 = MyThread('uzi')
t1.start()
t2.start()
if __name__ == '__main__':
main()
# dream is starting
# uzi is starting
# uzi is ending
# dream is ending
【三】一個程序下開啟多個執行緒和多個子程序的區別
【1】誰的開啟速度快
from threading import Thread
from multiprocessing import Process
import time
def work():
print('hello')
def timer(func):
def inner(*args, **kwargs):
start_time = time.time()
res = func(*args, **kwargs)
print(f'函式 {func.__name__} 執行時間為:{time.time() - start_time}')
return res
return inner
@timer
def work_process():
# 在主程序下開啟子程序
t = Process(target=work)
t.start()
@timer
def work_thread():
# 在主程序下開啟執行緒
t = Thread(target=work)
t.start()
if __name__ == '__main__':
work_thread()
work_process()
# hello
# 函式 work_thread 執行時間為:0.0009613037109375
# 函式 work_process 執行時間為:0.03390765190124512
# hello
【2】檢視pid
from threading import Thread
from multiprocessing import Process
import os
def work():
print(f"該程式pid:{os.getpid()}")
def work_thread():
# 在主程序下開啟多個執行緒,每個執行緒都跟主程序的pid一樣
t1 = Thread(target=work)
t2 = Thread(target=work)
t1.start()
t2.start()
def work_process():
# 開多個程序,每個程序都有不同的pid
p1 = Process(target=work)
p2 = Process(target=work)
p1.start()
p2.start()
if __name__ == '__main__':
work_thread()
# 該程式pid:100620
# 該程式pid:100620
work_process()
# 該程式pid:100772
# 該程式pid:103280
【3】同一程序內的執行緒共享該程序的資料
from threading import Thread
from multiprocessing import Process
def work():
global num
num = 0
def work_process():
num = 100
p = Process(target=work)
p.start()
p.join()
print(f'程序num:{num}') # 子程序p已經將自己的全域性的n改成了0,但改的僅僅是它自己的,檢視父程序的n仍然為100
# 程序num:100
def work_thread():
num = 1
t = Thread(target=work)
t.start()
t.join()
print(f'執行緒num:{num}') # 檢視結果為1,因為同一程序內的執行緒之間共享程序內的資料
# 執行緒num:1
if __name__ == '__main__':
# 多程序:子程序只改自己的
work_process()
# 多執行緒:資料發生錯亂,同一程序內的執行緒之間共享資料
work_thread()
【四】多執行緒併發的服務端
from threading import Thread
from socket import *
# 不寫引數:預設是TCP協議
# 建立伺服器物件
server = socket()
# 繫結 IP PORT
IP = '127.0.0.2'
PORT = 8081
ADDR = (IP, PORT)
server.bind(ADDR)
# 監聽
server.listen(5)
# 將接受處理資料部分封裝成函式呼叫
def run(conn):
while True:
from_client = conn.recv(1024)
# 接受的資訊為空時,會無限迴圈
if len(from_client) == 0:
break
# 接收到客戶端的資訊
print(f"這是來自客戶端的訊息:{from_client.decode()}")
# 返回給客戶端資訊
to_client = '你的訊息我已收到!'
conn.send(to_client.encode())
# 關閉連結
conn.close()
def main():
while True:
# 接受連線物件和 ip port
conn, addr = server.accept()
t = Thread(target=run, args=(conn,))
t.start()
if __name__ == '__main__':
main()
from socket import *
# 不寫引數:預設是TCP協議
# 建立客戶端物件
client = socket()
# 繫結 IP PORT
IP = '127.0.0.2'
PORT = 8081
ADDR = (IP, PORT)
client.connect(ADDR)
while True:
# 向服務端發資料
message = input("請輸入傳送給服務端的訊息:").strip()
client.send(message.encode())
# 接受伺服器返回的資料
data_from_server = client.recv(1024)
print(data_from_server.decode())
【五】執行緒物件的屬性和方法
【1】執行緒物件的 join 方法
from threading import Thread
import time
def task(name):
print(f'{name} is starting')
time.sleep(3)
print(f'{name} is ending')
def main():
t1 = Thread(target=task, args=('drake',))
t2 = Thread(target=task, args=('uzi',))
t1.start()
t2.start()
# 主執行緒等待子程序結束之後再執行
t1.join()
t2.join()
if __name__ == '__main__':
main()
# drake is starting
# uzi is starting
# drake is ending
# uzi is ending
【2】獲取當前程序的名字——current_thread
from threading import Thread, active_count, current_thread
import time
def task():
# 獲取當前執行緒的名字
print(f'該執行緒的名字:{current_thread().name}')
time.sleep(2)
def main():
t1 = Thread(target=task)
t2 = Thread(target=task)
t1.start()
t2.start()
print(f'該執行緒的名字:{current_thread().name}')
if __name__ == '__main__':
main()
# 該執行緒的名字:Thread - 1(task)
# 該執行緒的名字:Thread - 2(task)
# 該執行緒的名字:MainThread
【3】統計當前活躍的執行緒數——active_count
from threading import Thread, active_count, current_thread
import time
def task():
# 獲取當前執行緒的名字
print(f'該執行緒的名字:{current_thread().name}')
time.sleep(2)
def main():
t1 = Thread(target=task)
t2 = Thread(target=task)
t1.start()
t2.start()
# 統計當前活躍的執行緒數
print(f'當前活躍的執行緒數:{active_count()}')
print(f'該執行緒的名字:{current_thread().name}')
if __name__ == '__main__':
main()
# 該執行緒的名字:Thread - 1(task)
# 該執行緒的名字:Thread - 2(task)
# 當前活躍的執行緒數:3
# 該執行緒的名字:MainThread