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

python中的多線程實(shí)例教程

 更新時(shí)間:2014年08月27日 11:20:21   投稿:shichen2014  
這篇文章主要介紹了python中的多線程用法,包括線程的創(chuàng)建、同步等核心問(wèn)題,具有很好的參考借鑒價(jià)值,需要的朋友可以參考下

本文以實(shí)例形式較為詳細(xì)的講述了Python中多線程的用法,在Python程序設(shè)計(jì)中有著比較廣泛的應(yīng)用。分享給大家供大家參考之用。具體分析如下:

python中關(guān)于多線程的操作可以使用thread和threading模塊來(lái)實(shí)現(xiàn),其中thread模塊在Py3中已經(jīng)改名為_(kāi)thread,不再推薦使用。而threading模塊是在thread之上進(jìn)行了封裝,也是推薦使用的多線程模塊,本文主要基于threading模塊進(jìn)行介紹。在某些版本中thread模塊可能不存在,要使用dump_threading來(lái)代替threading模塊。

一、線程創(chuàng)建

threading模塊中每個(gè)線程都是一個(gè)Thread對(duì)象,創(chuàng)建一個(gè)線程有兩種方式,一種是將函數(shù)傳遞到Thread對(duì)象中執(zhí)行,另一種是從Thread繼承,然后重寫(xiě)run方法(是不是跟Java很像)。

下面使用這兩種方法分別創(chuàng)建一個(gè)線程并同時(shí)執(zhí)行

import random, threading
def threadFunction():
  for i in range(10):
    print 'ThreadFuction - %d'%i
    time.sleep(random.randrange(0,2))


class ThreadClass(threading.Thread):
  def __init__(self):
    threading.Thread.__init__(self);
    
  def run(self):
    for i in range(10):
      print 'ThreadClass - %d'%i
      time.sleep(random.randrange(0,2))

if __name__ == '__main__':
  tFunc = threading.Thread(target = threadFunction);
  tCls = ThreadClass()
  tFunc.start()
  tCls.start()

執(zhí)行結(jié)果如下,可以看到兩個(gè)線程在交替打印。至于空行和一行多個(gè)輸出,是因?yàn)镻y的print并不是線程安全的,在當(dāng)前線程的print打印了部分內(nèi)容后,準(zhǔn)備打印換行之前,被別的線程中的print搶先,在換行之前打印了其它的內(nèi)容。

ThreadFuction - 0
ThreadFuction - 1
ThreadFuction - 2
ThreadClass - 0
ThreadFuction - 3
ThreadClass - 1
ThreadFuction - 4
ThreadClass - 2
ThreadClass - 3
ThreadClass - 4ThreadFuction - 5

ThreadClass - 5
ThreadClass - 6
ThreadClass - 7
ThreadClass - 8
ThreadFuction - 6ThreadClass - 9

ThreadFuction - 7
ThreadFuction - 8
ThreadFuction - 9

Thread類(lèi)的構(gòu)造函數(shù)定義如下

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})

group: 留作ThreadGroup擴(kuò)展使用,一般沒(méi)什么用
target:新線程的任務(wù)函數(shù)名
name:  線程名,一般也沒(méi)什么用
args:  tuple參數(shù)
kwargs:dictionary參數(shù)

Thread類(lèi)的成員變量和函數(shù)如下

start()         啟動(dòng)一個(gè)線程
run()           線程執(zhí)行體,也是一般要重寫(xiě)的內(nèi)容
join([timeout]) 等待線程結(jié)束
name            線程名
ident           線程ID
daemon          是否守護(hù)線程
isAlive()、is_alive()    線程是否存活
getName()、setName()     Name的get&set方法
isDaemon()、setDaemon()  daemon的get&set方法

這里的守護(hù)線程與Linux中的守護(hù)進(jìn)程并不是一個(gè)概念。這里是指當(dāng)所有守護(hù)線程退出后主程序才會(huì)退出,否則即使線程任務(wù)沒(méi)有結(jié)束,只要不是守護(hù)線程,都會(huì)跟著主程序一起退出。而Linux中的守護(hù)進(jìn)程定義正好相反,守護(hù)進(jìn)程已經(jīng)脫離父進(jìn)程,不會(huì)隨著父進(jìn)程的結(jié)束而退出。

二、線程同步

線程同步是多線程中的一個(gè)核心問(wèn)題,threading模塊對(duì)線程同步有著良好的支持、包括線程特定數(shù)據(jù)、信號(hào)量、互斥鎖、條件變量等。

1.線程特定數(shù)據(jù)

簡(jiǎn)而言之,線程特定數(shù)據(jù)就是線程獨(dú)自持有的全局變量,相互之間的修改不會(huì)造成影響。

threading模塊中使用local()方法生成一個(gè)線程獨(dú)立對(duì)象,舉例如下,其中sleep(1)是為了保證讓子線程先運(yùn)行完再運(yùn)行接下來(lái)的語(yǔ)句。

data = threading.local()
def threadFunction():
  global data
  data.x = 3
  print threading.currentThread(), data.x
  
if __name__ == '__main__':
  data.x = 1
  tFunc = threading.Thread(target = threadFunction).start();
  time.sleep(1)
  print threading.current_thread(), data.x

<Thread(Thread-1, started 36208)> 3
<_MainThread(MainThread, started 35888)> 1

輸出如上,可以看到,Thread-1中對(duì)data.x的修改并沒(méi)有影響到主線程中data.x的值。

2.互斥鎖

threading中定義了兩種鎖:threading.Lock和threading.RLock。兩者的不同在于后者是可重入鎖,也就是說(shuō)在一個(gè)線程內(nèi)重復(fù)LOCK同一個(gè)鎖不會(huì)發(fā)生死鎖,這與POSIX中的PTHREAD_MUTEX_RECURSIVE也就是可遞歸鎖的概念是相同的。

關(guān)于互斥鎖的API很簡(jiǎn)單,只有三個(gè)函數(shù)————分配鎖,上鎖,解鎖。

threading.Lock()        分配一個(gè)互斥鎖
acquire([blocking=1])   上鎖(阻塞或者非阻塞,非阻塞時(shí)相當(dāng)于try_lock,通過(guò)返回False表示已經(jīng)被其它線程鎖住。)
release()               解鎖
下面通過(guò)一個(gè)例子來(lái)說(shuō)明互斥鎖的使用。在之前的例子中,多線程print會(huì)造成混亂的輸出,這里使用一個(gè)互斥鎖,來(lái)保證每行一定只有一個(gè)輸出。

def threadFunction(arg):
  while True:
    lock.acquire()
    print 'ThreadFuction - %d'%arg
    lock.release()

if __name__ == '__main__':
  lock = threading.Lock()
  threading.Thread(target = threadFunction, args=(1,)).start();
  threading.Thread(target = threadFunction, args=(2,)).start();

3.條件變量

條件變量總是與互斥鎖一起使用的,threading中的條件變量默認(rèn)綁定了一個(gè)RLock,也可以在初始化條件變量的時(shí)候傳進(jìn)去一個(gè)自己定義的鎖。

可用的函數(shù)如下

threading.Condition([lock]) 分配一個(gè)條件變量
acquire(*args)        條件變量上鎖
release()          條件變量解鎖
wait([timeout])       等待喚醒,timeout表示超時(shí)
notify(n=1)         喚醒最大n個(gè)等待的線程
notifyAll()、notify_all()  喚醒所有等待的線程
下面這個(gè)例子使用條件變量來(lái)控制兩個(gè)線程交替運(yùn)行

num = 0
def threadFunction(arg):
  global num
  while num < 10:
    cond.acquire()
    while num % 2 != arg:
      cond.wait()
    print 'Thread %d - %d' %(arg, num)
    num += 1
    cond.notify()
    cond.release()

if __name__ == '__main__':
  cond = threading.Condition()
  threading.Thread(target = threadFunction, args=(0,)).start();
  threading.Thread(target = threadFunction, args=(1,)).start();

輸出如下

Thread 0 - 0
Thread 1 - 1
Thread 0 - 2
Thread 1 - 3
Thread 0 - 4
Thread 1 - 5
Thread 0 - 6
Thread 1 - 7
Thread 0 - 8
Thread 1 - 9
Thread 0 - 10

其實(shí)上面這個(gè)程序是有問(wèn)題的,我們想打印的是0~9,但實(shí)際上10也被打印了出來(lái),原因很簡(jiǎn)單,因?yàn)閮蓚€(gè)線程交替打印,使得num在一個(gè)線程中可能加2,從而導(dǎo)致10被打印出來(lái),所以必須在打印前再次check。

相信本文所述對(duì)大家的Python程序設(shè)計(jì)有一定的借鑒價(jià)值。

相關(guān)文章

  • python中的List sort()與torch.sort()

    python中的List sort()與torch.sort()

    這篇文章主要介紹了python中的List sort()與torch.sort()使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • python定時(shí)任務(wù)schedule庫(kù)用法詳細(xì)講解

    python定時(shí)任務(wù)schedule庫(kù)用法詳細(xì)講解

    python中有一個(gè)輕量級(jí)的定時(shí)任務(wù)調(diào)度的庫(kù)schedule,下面這篇文章主要給大家介紹了關(guān)于python定時(shí)任務(wù)schedule庫(kù)用法的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-01-01
  • 使用python3+xlrd解析Excel的實(shí)例

    使用python3+xlrd解析Excel的實(shí)例

    今天小編就為大家分享一篇使用python3+xlrd解析Excel的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • 對(duì)numpy中二進(jìn)制格式的數(shù)據(jù)存儲(chǔ)與讀取方法詳解

    對(duì)numpy中二進(jìn)制格式的數(shù)據(jù)存儲(chǔ)與讀取方法詳解

    今天小編就為大家分享一篇對(duì)numpy中二進(jìn)制格式的數(shù)據(jù)存儲(chǔ)與讀取方法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • 三分鐘時(shí)間教你用Python繪制春聯(lián)

    三分鐘時(shí)間教你用Python繪制春聯(lián)

    大家好,本篇文章主要講的是三分鐘時(shí)間教你用Python繪制春聯(lián),感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • Python實(shí)現(xiàn)去除列表中重復(fù)元素的方法小結(jié)【4種方法】

    Python實(shí)現(xiàn)去除列表中重復(fù)元素的方法小結(jié)【4種方法】

    這篇文章主要介紹了Python實(shí)現(xiàn)去除列表中重復(fù)元素的方法,結(jié)合實(shí)例形式總結(jié)分析了Python列表去重的4種實(shí)現(xiàn)方法,涉及Python針對(duì)列表的遍歷、判斷、排序等相關(guān)操作技巧,需要的朋友可以參考下
    2018-04-04
  • python中的try except與R語(yǔ)言中的tryCatch異常解決

    python中的try except與R語(yǔ)言中的tryCatch異常解決

    這篇文章主要為大家介紹了python中的try except與R語(yǔ)言中的tryCatch異常解決的方式及分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-11-11
  • 使用Qt?QSS繪制簡(jiǎn)單美化界面功能

    使用Qt?QSS繪制簡(jiǎn)單美化界面功能

    這篇文章主要介紹了使用Qt?QSS繪制簡(jiǎn)單美化界面,本文以繪制登錄界面為例,創(chuàng)建一個(gè)繼承自Qwidget的設(shè)計(jì)師界面類(lèi),為了使得控件排放整齊有序,可以使用layout布局進(jìn)行輔助,感興趣的朋友跟隨小編一起看看吧
    2022-10-10
  • Python安裝時(shí)常見(jiàn)報(bào)錯(cuò)以及解決方案

    Python安裝時(shí)常見(jiàn)報(bào)錯(cuò)以及解決方案

    這篇文章主要介紹了在安裝Python、配置環(huán)境變量、使用pip以及運(yùn)行Python腳本時(shí)常見(jiàn)的錯(cuò)誤及其解決方案,文中介紹的非常詳細(xì),需要的朋友可以參考下
    2025-02-02
  • Python使用pandas處理CSV文件的實(shí)例講解

    Python使用pandas處理CSV文件的實(shí)例講解

    今天小編就為大家分享一篇Python使用pandas處理CSV文件的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06

最新評(píng)論

陇南市| 江西省| 新乐市| 岗巴县| 秭归县| 平利县| 乌兰察布市| 交城县| 安陆市| 汶川县| 南郑县| 共和县| 铁岭县| 鞍山市| 牙克石市| 东平县| 罗山县| 郓城县| 招远市| 潜江市| 济阳县| 东乡县| 射阳县| 开化县| 梅河口市| 宁强县| 德安县| 沙河市| 华宁县| 龙南县| 麻江县| 含山县| 台中县| 莱芜市| 眉山市| 巴彦县| 商城县| 奇台县| 开封县| 龙门县| 邯郸县|