最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Python多線程

 更新時間:2016年11月14日 11:59:46   作者:jiangsjj  
這篇文章主要為大家詳細(xì)介紹了Python多線程的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家解析了Python多線程,供大家參考,具體內(nèi)容如下

1、多線程的理解

多進(jìn)程和多線程都可以執(zhí)行多個任務(wù),線程是進(jìn)程的一部分。線程的特點是線程之間可以共享內(nèi)存和變量,資源消耗少(不過在Unix環(huán)境中,多進(jìn)程和多線程資源調(diào)度消耗差距不明顯,Unix調(diào)度較快),缺點是線程之間的同步和加鎖比較麻煩。

2、Python多線程創(chuàng)建

在Python中,同樣可以實現(xiàn)多線程,有兩個標(biāo)準(zhǔn)模塊thread和threading,不過我們主要使用更高級的threading模塊。使用例子:

import threading
import time
 
def target():
 print 'the curent threading %s is running' % threading.current_thread().name
 time.sleep(1)
 print 'the curent threading %s is ended' % threading.current_thread().name
 
print 'the curent threading %s is running' % threading.current_thread().name
t = threading.Thread(target=target)
 
t.start()
t.join()
print 'the curent threading %s is ended' % threading.current_thread().name
 

輸出:

the curent threading MainThread is running
the curent threading Thread-1 is running
the curent threading Thread-1 is ended
the curent threading MainThread is ended

start是啟動線程,join是阻塞當(dāng)前線程,即使得在當(dāng)前線程結(jié)束時,不會退出。從結(jié)果可以看到,主線程直到Thread-1結(jié)束之后才結(jié)束。

Python中,默認(rèn)情況下,如果不加join語句,那么主線程不會等到當(dāng)前線程結(jié)束才結(jié)束,但卻不會立即殺死該線程。如不加join輸出如下:

the curent threading MainThread is running
the curent threading Thread-1 is running
 the curent threading MainThread is ended
the curent threading Thread-1 is ended

但如果為線程實例添加t.setDaemon(True)之后,如果不加join語句,那么當(dāng)主線程結(jié)束之后,會殺死子線程。代碼:

import threading
import time
def target():
 print 'the curent threading %s is running' % threading.current_thread().name
 time.sleep(4)
 print 'the curent threading %s is ended' % threading.current_thread().name
print 'the curent threading %s is running' % threading.current_thread().name
t = threading.Thread(target=target)
t.setDaemon(True)
t.start()
t.join()
print 'the curent threading %s is ended' % threading.current_thread().name

輸出如下:

the curent threading MainThread is running
the curent threading Thread-1 is runningthe curent threading MainThread is ended

如果加上join,并設(shè)置等待時間,就會等待線程一段時間再退出:

import threading
import time
def target():
 print 'the curent threading %s is running' % threading.current_thread().name
 time.sleep(4)
 print 'the curent threading %s is ended' % threading.current_thread().name
print 'the curent threading %s is running' % threading.current_thread().name
t = threading.Thread(target=target)
t.setDaemon(True)
t.start()
t.join(1)

輸出:

the curent threading MainThread is running
the curent threading Thread-1 is running
the curent threading MainThread is ended

主線程等待1秒,就自動結(jié)束,并殺死子線程。如果join不加等待時間,t.join(),就會一直等待,一直到子線程結(jié)束,輸出如下:

the curent threading MainThread is running
the curent threading Thread-1 is running
the curent threading Thread-1 is ended
the curent threading MainThread is ended

3、線程鎖和ThreadLocal

(1)線程鎖

對于多線程來說,最大的特點就是線程之間可以共享數(shù)據(jù),那么共享數(shù)據(jù)就會出現(xiàn)多線程同時更改一個變量,使用同樣的資源,而出現(xiàn)死鎖、數(shù)據(jù)錯亂等情況。

假設(shè)有兩個全局資源,a和b,有兩個線程thread1,thread2. thread1占用a,想訪問b,但此時thread2占用b,想訪問a,兩個線程都不釋放此時擁有的資源,那么就會造成死鎖。

對于該問題,出現(xiàn)了Lock。 當(dāng)訪問某個資源之前,用Lock.acquire()鎖住資源,訪問之后,用Lock.release()釋放資源。

a = 3
lock = threading.Lock()
def target():
 print 'the curent threading %s is running' % threading.current_thread().name
 time.sleep(4)
 global a
 lock.acquire()
 try:
 a += 3
 finally:
 lock.release()
 print 'the curent threading %s is ended' % threading.current_thread().name
 print 'yes'

用finally的目的是防止當(dāng)前線程無線占用資源。

(2)ThreadLocal

介紹完線程鎖,接下來出場的是ThreadLocal。當(dāng)不想將變量共享給其他線程時,可以使用局部變量,但在函數(shù)中定義局部變量會使得在函數(shù)之間傳遞特別麻煩。ThreadLocal是非常牛逼的東西,它解決了全局變量需要枷鎖,局部變量傳遞麻煩的兩個問題。通過在線程中定義:

local_school = threading.local()

此時這個local_school就變成了一個全局變量,但這個全局變量只在該線程中為全局變量,對于其他線程來說是局部變量,別的線程不可更改。 def process_thread(name):# 綁定ThreadLocal的student: local_school.student = name

這個student屬性只有本線程可以修改,別的線程不可以。代碼:

local = threading.local()
def func(name):
 print 'current thread:%s' % threading.currentThread().name
 local.name = name
 print "%s in %s" % (local.name,threading.currentThread().name)
t1 = threading.Thread(target=func,args=('haibo',))
t2 = threading.Thread(target=func,args=('lina',))
t1.start()
t2.start()
t1.join()
t2.join()

從代碼中也可以看到,可以將ThreadLocal理解成一個dict,可以綁定不同變量。

ThreadLocal用的最多的地方就是每一個線程處理一個HTTP請求,在Flask框架中利用的就是該原理,它使用的是基于Werkzeug的LocalStack。

4、Map實現(xiàn)多線程

對于多線程的使用,我們經(jīng)常是用thread來創(chuàng)建,比較繁瑣:

class MyThread(threading.Thread):
 def init(self):
 threading.Thread.init(self)
def run(self):
 lock.acquire()
 print threading.currentThread().getName()
 lock.release()
 
def build_worker(num):
 workers = []
 for t in range(num):
 work = MyThread()
 work.start()
 workers.append(work)
 return workers
def producer():
 threads = build_worker(4)
 for w in threads:
 w.join()
 print 'Done'

如果要創(chuàng)建更多的線程,那就要一一加到里面,操作麻煩,代碼可讀性也變差。在Python中,可以使用map函數(shù)簡化代碼。map可以實現(xiàn)多任務(wù)的并發(fā),簡單示例:

復(fù)制代碼 代碼如下:
urls = ['http://www.baidu.com','http://www.sina.com','http://www.qq.com']
results=map(urllib2.urlopen,urls)

map將urls的每個元素當(dāng)做參數(shù)分別傳給urllib2.urlopen函數(shù),并最后把結(jié)果放到results列表中,map 函數(shù)一手包辦了序列操作、參數(shù)傳遞和結(jié)果保存等一系列的操作。 其原理:

map函數(shù)負(fù)責(zé)將線程分給不同的CPU。

在 Python 中有個兩個庫包含了 map 函數(shù): multiprocessing 和它鮮為人知的子庫 multiprocessing.dummy.dummy 是 multiprocessing 模塊的完整克隆,唯一的不同在于 multiprocessing 作用于進(jìn)程,而 dummy 模塊作用于線程。代碼:

import urllib2
 
from multiprocessing.dummy import Pool as ThreadPool
 
urls = ['http://www.baidu.com','http://www.sina.com','http://www.qq.com']
 
pool = ThreadPool()
 
results = pool.map(urllib2.urlopen,urls)
print results
pool.close()
pool.join()
 
print 'main ended'

pool = ThreadPool()創(chuàng)建了線程池,其默認(rèn)值為當(dāng)前機(jī)器 CPU 的核數(shù),可以指定線程池大小,不是越多越好,因為越多的話,線程之間的切換也是很消耗資源的。

results = pool.map(urllib2.urlopen,urls) 該語句將不同的url傳給各自的線程,并把執(zhí)行后結(jié)果返回到results中。

代碼清晰明了,巧妙得完成Threading模塊完成的功能。

5、Python多線程的缺陷:

上面說了那么多關(guān)于多線程的用法,但Python多線程并不能真正能發(fā)揮作用,因為在Python中,有一個GIL,即全局解釋鎖,該鎖的存在保證在同一個時間只能有一個線程執(zhí)行任務(wù),也就是多線程并不是真正的并發(fā),只是交替得執(zhí)行。假如有10個線程炮在10核CPU上,當(dāng)前工作的也只能是一個CPU上的線程。

6、Python多線程的應(yīng)用場景。

雖然Python多線程有缺陷,總被人說成是雞肋,但也不是一無用處,它很適合用在IO密集型任務(wù)中。I/O密集型執(zhí)行期間大部分是時間都用在I/O上,如數(shù)據(jù)庫I/O,較少時間用在CPU計算上。因此該應(yīng)用場景可以使用Python多線程,當(dāng)一個任務(wù)阻塞在IO操作上時,我們可以立即切換執(zhí)行其他線程上執(zhí)行其他IO操作請求。

總結(jié):Python多線程在IO密集型任務(wù)中還是很有用處的,而對于計算密集型任務(wù),應(yīng)該使用Python多進(jìn)程。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python??序列化反序列化和異常處理的問題小結(jié)

    Python??序列化反序列化和異常處理的問題小結(jié)

    這篇文章主要介紹了Python?序列化反序列化和異常處理,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-12-12
  • 解決Django中調(diào)用keras的模型出現(xiàn)的問題

    解決Django中調(diào)用keras的模型出現(xiàn)的問題

    今天小編就為大家分享一篇解決Django中調(diào)用keras的模型出現(xiàn)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • 使用Python的xlrd和xlwt操作Excel詳解

    使用Python的xlrd和xlwt操作Excel詳解

    這篇文章主要介紹了使用Python的xlrd和xlwt對比操作Excel詳解,xlrd和xlwt是python的第三方庫,xlrd模塊實現(xiàn)對excel文件內(nèi)容讀取,xlwt模塊實現(xiàn)對excel文件的寫入,需要的朋友可以參考下
    2023-08-08
  • Python如何自定義鄰接表圖類

    Python如何自定義鄰接表圖類

    這篇文章主要介紹了Python如何自定義鄰接表圖類問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Python畫圖學(xué)習(xí)入門教程

    Python畫圖學(xué)習(xí)入門教程

    這篇文章主要介紹了Python畫圖的方法,結(jié)合實例形式分析了Python基本的線性圖、餅狀圖等繪制技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2016-07-07
  • pycharm如何設(shè)置自動生成作者信息

    pycharm如何設(shè)置自動生成作者信息

    這篇文章主要介紹了pycharm如何設(shè)置自動生成作者信息,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Python散列表(Hash Table)的實現(xiàn)示例

    Python散列表(Hash Table)的實現(xiàn)示例

    散列表是一種常用于實現(xiàn)關(guān)聯(lián)數(shù)組或映射的數(shù)據(jù)結(jié)構(gòu),本文我們將深入講解Python中的散列表,包括散列函數(shù)、沖突解決方法、散列表的實現(xiàn)和應(yīng)用場景,感興趣的可以了解一下
    2024-01-01
  • Python 讀寫文件的操作代碼

    Python 讀寫文件的操作代碼

    本文通過實例代碼給大家介紹了Python 讀寫文件的操作方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-09-09
  • 使用Python實現(xiàn)獲取Apollo配置

    使用Python實現(xiàn)獲取Apollo配置

    Apollo是一款可靠的分布式配置管理中心,能夠集中化管理應(yīng)用不同環(huán)境、不同集群的配置,本文將介紹如何在Python項目中輕松獲取和使用Apollo配置中心的配置信息,需要的可以參考下
    2024-11-11
  • Python文件操作基礎(chǔ)流程解析

    Python文件操作基礎(chǔ)流程解析

    這篇文章主要介紹了Python文件操作基礎(chǔ)流程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03

最新評論

米林县| 长治县| 全南县| 米泉市| 共和县| 沂南县| 阿荣旗| 辽中县| 武平县| 盐边县| 深水埗区| 淳化县| 桃园县| 阜宁县| 诏安县| 宝清县| 油尖旺区| 凯里市| 麟游县| 龙州县| 锦屏县| 五大连池市| 深泽县| 肇东市| 黑龙江省| 高碑店市| 尚志市| 苏州市| 玉屏| 鄱阳县| 泰来县| 阿拉善左旗| 南涧| 思茅市| 沾益县| 大庆市| 灵山县| 延庆县| 都兰县| 梓潼县| 磴口县|