python程式解釋依靠直譯器主迴圈,主迴圈中同時只能有乙個控制線程在執行,類似單核cpu,是偽併發,python保證只有乙個執行緒執行的機制是使用全域性直譯器鎖gil,如下:
1.設定gil
2.切換乙個執行緒執行
3.執行指定數量的位元組碼指令或者執行緒yielding
4.設定執行緒為睡眠狀態
5.解鎖gil
呼叫外部**比如c或者c++的時候,gil會保持鎖定,因為此時沒有python位元組碼指令,
python提供了一些模組用於支援多執行緒程式設計,有thread,threading,queue等,一般不使用thread模組,因為缺少同步原語,主線程退出之後,其他執行緒都會在沒有清理的情況下直接退出,需要使用很笨拙的方法實現等待所有子程序,且沒有任何方法可以實現守護程序
thread模組元件:
start_new_thread(function, args, kwargs=none):核心函式,建立執行緒,第乙個引數是函式或者物件,第二個引數是函式引數,必須使用元組,沒有引數的話傳入空元組
allocate_lock:分配locktype鎖
exit():執行緒退出
locktype鎖物件的方法:
acquire(wait=none):嘗試獲取鎖
locked():獲取鎖物件,成功返回true,否則返回false
release():釋放鎖
thread模組實現同步的兩種笨拙方法:
1.主線程等待子執行緒執行的最長時間
2.每個字執行緒獲取乙個鎖,主線程迴圈檢查所有鎖都被釋放
threading模組元件:
thread:表示乙個執行執行緒的物件
lock:鎖原語物件,和thread模組一樣
rlock:可重入鎖,單個執行緒可以再次獲取已持有的鎖,即遞迴鎖
condition:條件變數
event:一定數量的執行緒等待某個事件發生,之後所有執行緒被啟用
semaphore:訊號量
timer:和thread類似,含有定時器的執行緒,執行前要等待一段時間
thread物件資料屬性:
name:執行緒名
ident:執行緒識別符號
daemon:是否是守護執行緒
thread物件方法:
__init__(group=none, target=none, name=none, args=(), kwargs={}, verbose=none, daemon=none):例項化乙個執行緒物件
start():執行執行緒
run():定義執行緒功能的方法,用於在子類中重寫
join(timeout=none):等待指定執行緒執行結束直到超時
getname():返回執行緒名
setname(name):設定執行緒名
isalive():執行緒是否存活
isdaemon():是否是守護執行緒
setdaemon(daemonic):設定守護執行緒標記,必須在start()之前設定才能生效
thread類建立執行緒的三種通用解決方案:
1.建立thread類的例項,傳入乙個函式
2.建立thread類的例項,傳入乙個可呼叫的類例項
3.派生thread類的子類,並建立子類的例項
python中函式是物件,因此給類定義__call__方法之後,可以使用方案2,但是**比較晦澀而且本質上和方案1沒有差別,因此一般使用方案1和方案3
乙個使用子類的解決方案如下:
# -*- coding: utf-8 -*-
#!/usr/bin/env python
import threading
from time import sleep, ctime
loops = [4, 2]
#繼承threading.thread類的乙個子類
class mythread(threading.thread):
def __init__(self, func, args, name = ''):
#呼叫父類的初始化函式
threading.thread.__init__(self)
self.name = name
self.func = func
self.args = args
#重寫run方法,使用start建立執行緒之後,會呼叫run方法
def run(self):
self.func(*self.args)
#執行緒方法
def loop(nloop, nsec):
print 'start loop ', nloop, ' at ', ctime()
sleep(nsec)
print 'loop ', nloop, ' done at ', ctime()
def main():
print 'starting at ', ctime()
threads =
nloops = range(len(loops))
#建立threading.thread的子類的例項
for i in nloops:
t = mythread(loop, (i, loops[i]), loop.__name__)
#建立執行緒
for i in nloops:
threads[i].start()
#主線程等待所有執行緒結束
for i in nloops:
threads[i].join()
print 'all done at ', ctime()
if __name__ == '__main__':
main()
一般將子類單獨做成乙個模組,這樣可以在其他python檔案中import,通用模版如下:
# -*- coding: utf-8 -*-
#!/usr/bin/env python
import threading
from time import ctime
class mythread(threading.thread):
def __init__(self, func, args, name = ''):
threading.thread.__init__(self)
self.name = name
self.func = func
self.args = args
#這樣很巧妙,若func有返回值的話,可以呼叫此函式獲取
def getresult(self):
return self.res
def run(self):
print 'starting', self.name, 'at', ctime()
self.res = self.func(*self.args)
print self.name, 'finished at', ctime()
activecount():當前活動的thread物件個數
currentthread():返回當前thread物件
enumerate():返回當前活動的thread物件列表
settrace(func):為所有執行緒設定trace函式
setprofile(func):為所有執行緒設定profile函式
stack_size(size=0):返回新建立程序的棧大小,或者為後續執行緒設定棧大小為size
python多執行緒 python多執行緒
通常來說,多程序適用於計算密集型任務,多執行緒適用於io密集型任務,如網路爬蟲。關於多執行緒和多程序的區別,請參考這個 下面將使用python標準庫的multiprocessing包來嘗試多執行緒的操作,在python中呼叫多執行緒要使用multiprocessing.dummy,如果是多程序則去掉...
python多執行緒詳解 Python多執行緒詳解
前言 由於最近的工作中一直需要用到python去處理資料,而在面對大量的資料時,python多執行緒的優勢就展現出來了。因而藉此機會,盡可能詳盡地來闡述python多執行緒。但對於其更底層的實現機制,在此不做深究,僅是對於之前的一知半解做個補充,也希望初學者能夠通過這篇文章,即便是照葫蘆畫瓢,也能夠...
python程式多執行緒 PYTHON多執行緒
在單執行緒的情況下,程式是逐條指令順序執行的。同一時間只做乙個任務,完成了乙個任務再進行下乙個任務。比如有5個人吃飯,單執行緒一次只允許乙個人吃,乙個人吃完了另乙個人才能接著吃,假如每個人吃飯都需要1分鐘,5個人就需要5分鐘。多執行緒的情況下,程式就會同時進行多個任務,雖然在同一時刻也只能執行某個任...