執行緒是乙個基本的 cpu 執行單元。它必須依託於程序存活。乙個執行緒是乙個execution context(執行上下文),即乙個 cpu 執行時所需要的一串指令
因作用不同劃分為不同的型別:
gil只在cpython中才有,而在其他直譯器pypy和jython中是沒有gil的。
由於 gil 鎖存在,python 裡乙個程序永遠只能同時執行乙個執行緒(拿到 gil 的執行緒才能執行),這就是為什麼在多核cpu上,python 的多執行緒效率並不高的根本原因
python提供兩個模組進行多執行緒的操作,分別是thread和threading,前者是比較低階的模組,用於更底層的操作,一般應用級別的開發不常用。
import threading
def run(n):
print("current task:", n)
if __name__ == "__main__":
t1 = threading.thread(target=run, args=("thread 1",))
t2 = threading.thread(target=run, args=("thread 2",))
t1.start()
t2.start()
import threading
class mythread(threading.thread):
def __init__(self, n):
super(mythread, self).__init__() # 重構run函式必須要寫
self.n = n
def run(self):
print("current task:", self.n)
if __name__ == "__main__":
t1 = mythread("thread 1")
t2 = mythread("thread 2")
t1.start() #start之後執行run方法
t2.start()
join函式是將該執行緒加入到主線程中,
依次執行每個join的執行緒,執行完畢後繼續往下執行,不會同時執行。
主線程結束後,子執行緒還在執行,join函式使得主線程等到子執行緒結束時才退出。
import threading
def count(n):
while n > 0:
n -= 1
if __name__ == "__main__":
t1 = threading.thread(target=count, args=("100000",))
t2 = threading.thread(target=count, args=("100000",))
t1.start()
t2.start()
# 將 t1 和 t2 加入到主線程中
t1.join()
t2.join()
執行緒之間資料共享的。當多個執行緒對某乙個共享資料進行操作時,就需要考慮到執行緒安全問題。threading模組中定義了lock 類,提供了互斥鎖的功能來保證多執行緒情況下資料的正確性。
#建立鎖
mutex = threading.lock()
#鎖定mutex.acquire([timeout])
#釋放mutex.release()
可選引數timeout, 如果設定了timeout,則在超時後通過返回值可以判斷是否得到了鎖,從而可以進行一些其他的處理。
import threading
import time
num = 0
mutex = threading.lock()
class mythread(threading.thread):
def run(self):
global num
time.sleep(1)
if mutex.acquire(1):
num = num + 1
msg = self.name + ': num value is ' + str(num)
print(msg)
mutex.release()
if __name__ == '__main__':
for i in range(5):
t = mythread()
t.start()
滿足在同一執行緒中多次請求同一資源的需求。python 提供了可重入鎖(rlock)。
rlock內部維護著乙個lock和乙個counter變數,counter 記錄了 acquire 的次數,從而使得資源可以被多次 require。直到乙個執行緒所有的 acquire 都被 release,其他的執行緒才能獲得資源。
#建立 rlock
mutex = threading.rlock()
class mythread(threading.thread):
def run(self):
if mutex.acquire(1):
print("thread " + self.name + " get mutex")
time.sleep(1)
mutex.acquire()
mutex.release()
mutex.release()
如果希望主線程執行完畢之後,不管子執行緒是否執行完畢都隨著主線程一起結束。我們可以使用setdaemon(bool)函式,它跟join函式是相反的。它的作用是設定子執行緒是否隨主線程一起結束,必須在start() 之前呼叫,預設為false
class timelimited(thread): #class中的兩個函式是必須的
def __init__(self):
thread.__init__(self)
def run(self):
func(params)
t = timelimited()
t.setdaemon(true) #這個使用者執行緒必須設定在start()前面
t.start()
t.join(timeout=time_limited)
if t.is_alive():
raise exception('連線超時')
規定函式在多少秒後執行某個操作
import threading
def func1(a):
print('do something')
a+=1
print(a)
print('當前執行緒數為{}'.format(threading.activecount()))
if a>5:
return
t=threading.timer(5,func1,(a,))
t.start()
python多執行緒 python多執行緒
通常來說,多程序適用於計算密集型任務,多執行緒適用於io密集型任務,如網路爬蟲。關於多執行緒和多程序的區別,請參考這個 下面將使用python標準庫的multiprocessing包來嘗試多執行緒的操作,在python中呼叫多執行緒要使用multiprocessing.dummy,如果是多程序則去掉...
python多執行緒詳解 Python多執行緒詳解
前言 由於最近的工作中一直需要用到python去處理資料,而在面對大量的資料時,python多執行緒的優勢就展現出來了。因而藉此機會,盡可能詳盡地來闡述python多執行緒。但對於其更底層的實現機制,在此不做深究,僅是對於之前的一知半解做個補充,也希望初學者能夠通過這篇文章,即便是照葫蘆畫瓢,也能夠...
python程式多執行緒 PYTHON多執行緒
在單執行緒的情況下,程式是逐條指令順序執行的。同一時間只做乙個任務,完成了乙個任務再進行下乙個任務。比如有5個人吃飯,單執行緒一次只允許乙個人吃,乙個人吃完了另乙個人才能接著吃,假如每個人吃飯都需要1分鐘,5個人就需要5分鐘。多執行緒的情況下,程式就會同時進行多個任務,雖然在同一時刻也只能執行某個任...