1.主線程:建立乙個程序的時候,會創造乙個執行緒,這個執行緒就被成為主線程
乙個程序裡只有乙個主線程
注意:python中的多執行緒不是真正意義上的多執行緒。(高速的在多個執行緒中進行切換,製造出多執行緒的假象)
2.全域性鎖(gil): 在任意的指定時間裡,有且只有乙個執行緒在執行(保證python執行緒安全)
3.join:等待上面的所有執行緒結束之後在繼續往下執行
執行緒安全的歧義:
乙個程式的複雜度,和**長度有關
用於資料庫連線池
5.io操作多執行緒,必須要lock,acquire,release,rlock
互斥鎖:多執行緒對同乙個檔案進行操作時,當乙個執行緒在操作時候,其它執行緒不能進行操作,直到該執行緒結束後,才能進行操作
加鎖:acquire
釋放鎖:release
死鎖:加鎖後不釋放
防止死鎖:rlock(可重入),在加鎖中在加鎖,(幾個加鎖要有幾個解鎖)
守護執行緒:
必須在start()
方法呼叫之前設定,如果不設定為守護執行緒程式會被無限掛起。子執行緒啟動後,父執行緒也繼續執行下去,當父執行緒執行完最後一條語句後,沒有等待子執行緒,直接就退出了,同時子執行緒也一同結束。
上下文:每個執行緒都有他自己的一組cpu暫存器,稱為執行緒的上下文,該上下文反映了執行緒上次執行該執行緒的
cpu暫存器的狀態。
指令指標和堆疊指標暫存器:是執行緒上下文中兩個最重要的暫存器,執行緒總是在程序得到上下文中執行的,這些位址都用於標誌擁有執行緒的程序位址空間中的記憶體。
注意:加鎖後一定要釋放
執行緒可以被搶占(中斷)。
在其他執行緒正在執行時,執行緒可以暫時擱置(也稱為睡眠)
-- 這就是執行緒的退讓。
threading模組除了包含_thread模組中的所有方法外,還提供的其他方法:
執行緒模組同樣提供了
thread
類來處理執行緒,
thread
類提供了以下方法
:
eg1:
# threading.thread 繼承建立乙個新的子類,並例項化後呼叫 start() 方法啟動新執行緒,即它呼叫了執行緒的 run() 方法:
import threading, time
class my(threading.thread):
def __init__(self, id, name, counter):
super().__init__()
self.id = id
self.name = name
self.counter = counter
def run(self):
print("開始")
display(self.id, self.name, self.counter)
print("結束")
def display(id, name, counter):
for i in range(counter):
print("id:{},name:{}".format(id, name))
time.sleep(1.0)
t1 = my(1, "t1", 5)
t2 = my(2, "t2", 5)
t1.start()
t2.start()
t1.join()
t2.join()
print("退出主線程")
實行結果:
開始id:1,name:t1
開始id:2,name:t2
id:1,name:t1
id:2,name:t2
id:1,name:t1
id:2,name:t2
id:2,name:t2
id:1,name:t1
id:1,name:t1
id:2,name:t2
結束結束
退出主線程
eg2:
# 執行緒優先順序佇列( queue)
import queue, time, threading
# 迴圈標誌
queue_*** = 0
# 自定義執行緒,繼續threading.thread
class mythreading(threading.thread):
# 重寫初始化方法,實現物件屬性的賦值
def __init__(self, id, name, queue1):
threading.thread.__init__(self)
self.name = name
self.id = id
self.queue1 = queue1
# 例項化物件呼叫start()方法時候,會自動呼叫run()方法
def run(self):
print("開始:{}".format(self.name))
display(self.id, self.name, self.queue1)
print("結束:{}".format(self.name))
# 當佇列不為空的時候,列印乙個佇列元素,使用執行緒鎖
def display(id, name, queue1):
while not queue_***:
lock.acquire()
# print(name)
if not queue1.empty():
print("id:{}, name:{}, queue:{} ".format(id, name, queue1.get()))
lock.release()
else:
lock.release()
time.sleep(1)
# 建立乙個執行緒鎖物件
lock = threading.lock()
# 建立乙個做大長度為100的佇列
queue1 = queue.queue(100)
# 執行緒名稱列表
list1 = ["thread1", "thread2", "thread3", "thread4"]
# 建立執行緒物件後,新增的列表
list_thread =
id = 1
# 迴圈list1列表,建立物件,執行start()方法
for i in list1:
a = mythreading(id, i, queue1)
a.start()
# 新增到list_thread列表
id += 1
# 建立列表,並新增佇列元素
list2 = [i for i in range(5)]
lock.acquire()
for i in list2:
queue1.put(i)
lock.release()
# 當佇列不為空的時候,不進行主線程操作
while not queue1.empty():
pass
# 結束迴圈
queue_*** = 1
#使當前多線完成後,在繼續執行主線程
for i in list_thread:
i.join()
print("多執行緒結束")
實行結果:
開始id:1,name:t1
id:1,name:t1
id:1,name:t1
結束開始
id:2,name:t2
id:2,name:t2
id:2,name:t2
結束退出主線程
開始:thread1
開始:thread2
開始:thread3
開始:thread4
id:4, name:thread4, queue:0
id:2, name:thread2, queue:1
id:3, name:thread3, queue:2
id:1, name:thread1, queue:3
id:4, name:thread4, queue:4
結束:thread2
結束:thread3
結束:thread1
結束:thread4
多執行緒結束
python多執行緒 python多執行緒
通常來說,多程序適用於計算密集型任務,多執行緒適用於io密集型任務,如網路爬蟲。關於多執行緒和多程序的區別,請參考這個 下面將使用python標準庫的multiprocessing包來嘗試多執行緒的操作,在python中呼叫多執行緒要使用multiprocessing.dummy,如果是多程序則去掉...
python多執行緒詳解 Python多執行緒詳解
前言 由於最近的工作中一直需要用到python去處理資料,而在面對大量的資料時,python多執行緒的優勢就展現出來了。因而藉此機會,盡可能詳盡地來闡述python多執行緒。但對於其更底層的實現機制,在此不做深究,僅是對於之前的一知半解做個補充,也希望初學者能夠通過這篇文章,即便是照葫蘆畫瓢,也能夠...
python程式多執行緒 PYTHON多執行緒
在單執行緒的情況下,程式是逐條指令順序執行的。同一時間只做乙個任務,完成了乙個任務再進行下乙個任務。比如有5個人吃飯,單執行緒一次只允許乙個人吃,乙個人吃完了另乙個人才能接著吃,假如每個人吃飯都需要1分鐘,5個人就需要5分鐘。多執行緒的情況下,程式就會同時進行多個任務,雖然在同一時刻也只能執行某個任...