一、線程的創建和啓動
import threading
# 編寫一個普通的函數,作爲線程執行體
def action(max):
for i in range(max):
print(threading.current_thread().getName() + " " + str(i))
for i in range(100):
print(threading.current_thread().getName() + " " + str(i))
if i == 20:
# 創建線程1
t1 = threading.Thread(target=action, args=(100,))
t1.start()
# 創建線程2
t2 = threading.Thread(target=action, args=(100,))
t2.start()
print('主線程執行完成')
# 繼承thread類創建線程類
import threading
class FKThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.i = 0
# 重寫run方法
def run(self):
while self.i < 100:
print(threading.current_thread().getName() + " " + str(self.i))
self.i += 1
# 下面是主線程
for i in range(100):
print(threading.current_thread().getName() + " " + str(i))
if i == 20:
ft1 = FKThread()
ft1.start()
ft2 = FKThread()
ft2.start()
print('主線程執行完成')
二、線程的生命週期
三、控制線程
# join線程
import threading
def action(max):
for i in range(max):
print(threading.current_thread().name + " " + str(i))
threading.Thread(target=action, args=(100,), name='新線程').start()
for i in range(100):
if i == 20:
jt = threading.Thread(target=action, args=(100,), name="被join的線程")
jt.start()
jt.join()
print(threading.current_thread().name + " " + str(i))
#後臺守護線程
import threading
def action(max):
for i in range(max):
print(threading.current_thread().name + " " + str(i))
t = threading.Thread(target=action,args=(100,),name='守護線程')
#將線程設置爲守護線程
t.daemon = True
t.start()
#線程睡眠 sleep
import time
for i in range(10):
print('當前時間:%s' % time.ctime())
#休眠1秒
time.sleep(1)
四、線程同步
class Account:
# 構造方法
def __init__(self, account_no, balance):
self.account_no = account_no
self._balance = balance
# 獲取一個可重入鎖
self.lock = threading.RLock
def getBalance(self):
return self.balance
def draw(self, draw_aount):
# 上鎖
self.lock.acquire()
try:
if self._balance >= draw_aount:
print(threading.current_thread().name + "取錢成功!吐出鈔票" + str(draw_aount))
time.sleep(0.001)
self._balance -= draw_aount
print('餘額:' + str(self._balance))
else:
print(threading.current_thread().name + "取錢失敗,餘額不足!" + str(draw_aount))
except Exception as e:
print(e)
finally:
# 釋放鎖
self.lock.release()
def draw(account,draw_aount):
account.draw(draw_aount)
acct = Account('1234567',1000)
threading.Thread(name='甲',target=draw,args=(acct,800)).start()
threading.Thread(name='乙',target=draw,args=(acct,800)).start()
五、線程通信
class Account:
# 構造方法
def __init__(self, account_no, balance):
self.account_no = account_no
self._balance = balance
self.cond = threading.Condition()
# 定義是否已經存錢的標識
self._flag = False
def getBalance(self):
return self.balance
def draw(self, draw_aount):
# 上鎖
self.cond.acquire()
try:
# 如果flag是False,表明賬戶中還沒有存錢,取錢方法被阻塞
if not self._flag:
self.cond.wait()
else:
print(threading.current_thread().name + "取錢:" + str(draw_aount))
self._balance -= draw_aount
print("賬戶餘額爲:" + str(self._balance))
self._flag = False
self.cond.notify_all()
except Exception as e:
print(e)
finally:
# 釋放鎖
self.cond.release()
def deposit(self, deposit_amount):
self.cond.acquire()
try:
# 如果flag標識是True,則說明賬戶有錢,存錢方法被阻塞
if self._flag:
self.cond.wait()
else:
print(threading.current_thread().name + "存款" + str(deposit_amount))
self._balance += deposit_amount
self._flag = True
self.cond.notify_all()
except Exception as e:
print(e)
finally:
self.cond.release()
#使用queue隊列控制線程通信
import threading
import time
import queue
def product(bq):
str_tupln = ('python','kotlin','swift')
for i in range(99999):
print(threading.current_thread().name+"生產者準備生產元組元素")
time.sleep(0.2)
bq.put(str_tupln[i%3])
print(threading.current_thread().name+"生產者生產元素完成!")
def consume(bq):
while True:
print(threading.current_thread().name+"消費者準備消費元組元素")
time.sleep(0.2)
t = bq.get()
print(threading.current_thread().name+"消費者消費【%s】元素完成!" % t)
bq = queue.Queue(maxsize=1)
#啓動三個線程生產元素
threading.Thread(name='1',target=product,args=(bq,)).start()
threading.Thread(name='2',target=product,args=(bq,)).start()
threading.Thread(name='3',target=product,args=(bq,)).start()
#啓動一個線程消費元素
threading.Thread(name='4',target=consume,args=(bq,)).start()
六、線程池
from concurrent.futures import ThreadPoolExecutor
import threading
import time
def action(max):
my_sum = 0
for i in range(max):
print(threading.current_thread().name + " " + str(i))
my_sum += 1
return my_sum
# 創建一個包含兩個線程的線程池
pool = ThreadPoolExecutor(max_workers=2)
f1 = pool.submit(action, 50)
f2 = pool.submit(action, 50)
# 判斷f1代表的任務是否結束
print(f1.done)
time.sleep(3)
# 判斷f2代表的任務是否結束
print(f2.done)
#調用result方法會阻塞當前任務,直至當前任務完成
print(f1.result(), f2.result())
#關閉線程池
pool.shutdown()
七、線程相關類
#定時器
from threading import Timer
def hello():
print("hello world")
t = Timer(10.0,hello)
t.start()
from threading import Timer
import time
count = 0
def print_time():
print("當前時間:"+time.ctime())
global t,count
count+=1
if count < 10:
t = Timer(1,print_time)
t.start()
t = Timer(1,print_time)
t.start()
import sched,time
import threading
#定義線程調度器
s = sched.scheduler()
def print_time(name='default'):
print('%s的時間:%s' % (name,time.ctime()))
print('主線程',time.ctime())
#指定10秒後執行print_time函數
s.enter(10,1,print_time())
s.enter(5,2,print_time,argument=('位置參數',))
s.enter(5,1,print_time,kwargs={'name':'關鍵字參數'})
s.run()
print('主線程',time.ctime())
八、多進程