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

python 實(shí)現(xiàn)線程之間的通信示例

 更新時(shí)間:2020年02月14日 11:46:14   作者:三只松鼠  
這篇文章主要介紹了python 實(shí)現(xiàn)線程之間的通信示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言:因?yàn)镚IL的限制,python的線程是無法真正意義上并行的。相對(duì)于異步編程,其性能可以說不是一個(gè)等量級(jí)的。為什么我們還要學(xué)習(xí)多線程編程呢,雖然說異步編程好處多,但編程也較為復(fù)雜,邏輯不容易理解,學(xué)習(xí)成本和維護(hù)成本都比較高。畢竟我們大部分人還是適應(yīng)同步編碼的,除非一些需要高性能處理的地方采用異步。

首先普及下進(jìn)程和線程的概念:

進(jìn)程:進(jìn)程是操作系統(tǒng)資源分配的基本單位。

線程:線程是任務(wù)調(diào)度和執(zhí)行的基本單位。

一個(gè)應(yīng)用程序至少一個(gè)進(jìn)程,一個(gè)進(jìn)程至少一個(gè)線程。

兩者區(qū)別:同一進(jìn)程內(nèi)的線程共享本進(jìn)程的資源如內(nèi)存、I/O、cpu等,但是進(jìn)程之間的資源是獨(dú)立的。

一、多線程

python 可以通過 thread 或 threading 模塊實(shí)現(xiàn)多線程,threading 相比 thread 提供了更高階、更全面的線程管理。我們下文主要以 threading 模塊介紹多線程的基本用法。

import threading
import time

class thread(threading.Thread):
 def __init__(self, threadname):
 threading.Thread.__init__(self, name='線程' + threadname)

 def run(self):
 print('%s:Now timestamp is %s'%(self.name,time.time()))

threads = []
for a in range(int(5)): # 線程個(gè)數(shù)
 threads.append(thread(str(a)))
for t in threads: # 開啟線程
 t.start()
for t in threads: # 阻塞線程
 t.join()
print('END')

輸出:
線程3:Now timestamp is 1557386184.7574518
線程2:Now timestamp is 1557386184.7574518
線程0:Now timestamp is 1557386184.7574518
線程1:Now timestamp is 1557386184.7574518
線程4:Now timestamp is 1557386184.7582724
END

 start() 方法開啟子線程。運(yùn)行多次 start() 方法代表開啟多個(gè)子線程。

 join() 方法用來阻塞主線程,等待子線程執(zhí)行完成。舉個(gè)例子,主線程A創(chuàng)建了子線程B,并使用了 join() 方法,主線程A在 join() 處就被阻塞了,等待子線程B完成后,主線程A才能執(zhí)行 print('END')。如果沒有使用 join() 方法,主線程A創(chuàng)建子線程B后,不會(huì)等待子線程B,直接執(zhí)行 print('END'),如下:

import threading
import time

class thread(threading.Thread):
 def __init__(self, threadname):
 threading.Thread.__init__(self, name='線程' + threadname)

 def run(self):
 time.sleep(1)
 print('%s:Now timestamp is %s'%(self.name,time.time()))

threads = []
for a in range(int(5)): # 線程個(gè)數(shù)
 threads.append(thread(str(a)))
for t in threads: # 開啟線程
 t.start()
# for t in threads: # 阻塞線程
# t.join()
print('END')

輸出:
END
線程0:Now timestamp is 1557386321.376941
線程3:Now timestamp is 1557386321.377937
線程1:Now timestamp is 1557386321.377937
線程2:Now timestamp is 1557386321.377937
線程4:Now timestamp is 1557386321.377937

二、線程之間的通信

1.threading.Lock()

如果多個(gè)線程對(duì)某一資源同時(shí)進(jìn)行修改,可能會(huì)存在不可預(yù)知的情況。為了修改數(shù)據(jù)的正確性,需要把這個(gè)資源鎖住,只允許線程依次排隊(duì)進(jìn)去獲取這個(gè)資源。當(dāng)線程A操作完后,釋放鎖,線程B才能進(jìn)入。如下腳本是開啟多個(gè)線程修改變量的值,但輸出結(jié)果每次都不一樣。

import threading

money = 0
def Order(n):
 global money
 money = money + n
 money = money - n

class thread(threading.Thread):
 def __init__(self, threadname):
 threading.Thread.__init__(self, name='線程' + threadname)
 self.threadname = int(threadname)

 def run(self):
 for i in range(1000000):
  Order(self.threadname)

t1 = thread('1')
t2 = thread('5')
t1.start()
t2.start()
t1.join()
t2.join()
print(money)

接下來我們用 threading.Lock() 鎖住這個(gè)變量,等操作完再釋放這個(gè)鎖。lock.acquire() 給資源加一把鎖,對(duì)資源處理完成之后,lock.release() 再釋放鎖。以下腳本執(zhí)行結(jié)果都是一樣的,但速度會(huì)變慢,因?yàn)榫€程只能一個(gè)個(gè)的通過。

import threading

money = 0
def Order(n):
 global money
 money = money + n
 money = money - n

class thread(threading.Thread):
 def __init__(self, threadname):
 threading.Thread.__init__(self, name='線程' + threadname)
 self.threadname = int(threadname)

 def run(self):
 for i in range(1000000):
  lock.acquire()
  Order(self.threadname)
  lock.release()
# print('%s:Now timestamp is %s'%(self.name,time.time()))

lock = threading.Lock()
t1 = thread('1')
t2 = thread('5')
t1.start()
t2.start()
t1.join()
t2.join()
print(money)

2.threading.Rlock()

用法和 threading Lock() 一致,區(qū)別是 threading.Rlock() 允許多次鎖資源,acquire() 和 release() 必須成對(duì)出現(xiàn),也就是說加了幾把鎖就得釋放幾把鎖。

lock = threading.Lock()
# 死鎖
lock.acquire()
lock.acquire()
print('...')
lock.release()
lock.release()

rlock = threading.RLock()
# 同一線程內(nèi)不會(huì)阻塞線程
rlock.acquire()
rlock.acquire()
print('...')
rlock.release()
rlock.release()

3.threading.Condition()

threading.Condition() 可以理解為更加高級(jí)的鎖,比 Lock 和 Rlock 的用法更高級(jí),能處理一些復(fù)雜的線程同步問題。threading.Condition() 創(chuàng)建一把資源鎖(默認(rèn)是Rlock),提供 acquire() 和 release() 方法,用法和 Rlock 一致。此外 Condition 還提供 wait()、Notify() 和 NotifyAll() 方法。

wait():線程掛起,直到收到一個(gè) Notify() 通知或者超時(shí)(可選參數(shù)),wait() 必須在線程得到 Rlock 后才能使用。

Notify() :在線程掛起的時(shí)候,發(fā)送一個(gè)通知,讓 wait() 等待線程繼續(xù)運(yùn)行,Notify() 也必須在線程得到 Rlock 后才能使用。 Notify(n=1),最多喚醒 n 個(gè)線程。

NotifyAll() :在線程掛起的時(shí)候,發(fā)送通知,讓所有 wait() 阻塞的線程都繼續(xù)運(yùn)行。

舉例說明下 Condition() 使用

import threading,time

def TestA():
 cond.acquire()
 print('李白:看見一個(gè)敵人,請(qǐng)求支援')
 cond.wait()
 print('李白:好的')
 cond.notify()
 cond.release()

def TestB():
 time.sleep(2)
 cond.acquire()
 print('亞瑟:等我...')
 cond.notify()
 cond.wait()
 print('亞瑟:我到了,發(fā)起沖鋒...')

if __name__=='__main__':
 cond = threading.Condition()
 testA = threading.Thread(target=TestA)
 testB = threading.Thread(target=TestB)
 testA.start()
 testB.start()
 testA.join()
 testB.join()

輸出
李白:看見一個(gè)敵人,請(qǐng)求支援
亞瑟:等我...
李白:好的
亞瑟:我到了,發(fā)起沖鋒...

4.threading.Event()

threading.Event() 原理是在線程中立了一個(gè) Flag ,默認(rèn)值是 False ,當(dāng)一個(gè)或多個(gè)線程遇到 event.wait() 方法時(shí)阻塞,直到 Flag 值 變?yōu)?True 。threading.Event() 通常用來實(shí)現(xiàn)線程之間的通信,使一個(gè)線程等待其他線程的通知 ,把 Event 傳遞到線程對(duì)象中。

event.wait() :阻塞線程,直到 Flag 值變?yōu)?True

event.set() :設(shè)置 Flag 值為 True

event.clear() :修改 Flag 值為 False

event.isSet() :  僅當(dāng) Flag 值為 True 時(shí)返回

下面這個(gè)例子,主線程啟動(dòng)子線程后 sleap 2秒,子線程因?yàn)?event.wait() 被阻塞。當(dāng)主線程醒來后執(zhí)行 event.set() ,子線程才繼續(xù)運(yùn)行,兩者輸出時(shí)間差 2s。

import threading
import datetime,time

class thread(threading.Thread):
 def __init__(self, threadname):
 threading.Thread.__init__(self, name='線程' + threadname)
 self.threadname = int(threadname)

 def run(self):
 event.wait()
 print('子線程運(yùn)行時(shí)間:%s'%datetime.datetime.now())

if __name__ == '__main__':
 event = threading.Event()
 t1 = thread('0')
 #啟動(dòng)子線程
 t1.start()
 print('主線程運(yùn)行時(shí)間:%s'%datetime.datetime.now())
 time.sleep(2)
 # Flag設(shè)置成True
 event.set()
 t1.join()

輸出
主線程運(yùn)行時(shí)間:2019-05-30 15:51:49.690872
子線程運(yùn)行時(shí)間:2019-05-30 15:51:51.691523

 5.其他方法

threading.active_count():返回當(dāng)前存活的線程對(duì)象的數(shù)量

threading.current_thread():返回當(dāng)前線程對(duì)象

threading.enumerate():返回當(dāng)前所有線程對(duì)象的列表

threading.get_ident():返回線程pid

threading.main_thread():返回主線程對(duì)象

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

相關(guān)文章

  • python判斷設(shè)備是否聯(lián)網(wǎng)的方法

    python判斷設(shè)備是否聯(lián)網(wǎng)的方法

    這篇文章主要為大家詳細(xì)介紹了python判斷設(shè)備是否聯(lián)網(wǎng)的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • flask入門之文件上傳與郵件發(fā)送示例

    flask入門之文件上傳與郵件發(fā)送示例

    本篇文章主要介紹了flask入門之文件上傳與郵件發(fā)送示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • Python3使用Selenium獲取session和token方法詳解

    Python3使用Selenium獲取session和token方法詳解

    這篇文章主要介紹了Python3使用Selenium獲取session和token方法詳解,需要的朋友可以參考下
    2021-02-02
  • 在python中調(diào)用C/C++的三種方法

    在python中調(diào)用C/C++的三種方法

    這篇文章主要給大家介紹了關(guān)于在python中調(diào)用C/C++的三種方法,Python可以通過調(diào)用C/C++接口來實(shí)現(xiàn)與C/C++語言的交互,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • 初步解析Python中的yield函數(shù)的用法

    初步解析Python中的yield函數(shù)的用法

    這篇文章主要介紹了Python中的yield函數(shù),yield函數(shù)是生成器中的一個(gè)常用函數(shù),本文來自于IBM官方網(wǎng)站的開發(fā)者文檔的翻譯,需要的朋友可以參考下
    2015-04-04
  • django模板獲取list中指定索引的值方式

    django模板獲取list中指定索引的值方式

    這篇文章主要介紹了django模板獲取list中指定索引的值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • 使用Python編寫vim插件的簡單示例

    使用Python編寫vim插件的簡單示例

    這篇文章主要介紹了使用Python編寫vim插件的簡單教程,文中舉了一個(gè)獲取reddit首頁信息并顯示在緩沖區(qū)中的例子,需要的朋友可以參考下
    2015-04-04
  • 爬蟲使用IP來隱藏真實(shí)地址的過程(python示例)

    爬蟲使用IP來隱藏真實(shí)地址的過程(python示例)

    這篇文章主要為大家介紹了爬蟲使用IP來隱藏真實(shí)地址的過程(python示例)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • python將字符串轉(zhuǎn)換成數(shù)組的方法

    python將字符串轉(zhuǎn)換成數(shù)組的方法

    這篇文章主要介紹了python將字符串轉(zhuǎn)換成數(shù)組的方法,涉及Python操作字符串與數(shù)組的相關(guān)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-04-04
  • Python Tkinter模塊 GUI 可視化實(shí)例

    Python Tkinter模塊 GUI 可視化實(shí)例

    今天小編就為大家分享一篇Python Tkinter模塊 GUI 可視化實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11

最新評(píng)論

博白县| 昌乐县| 湟源县| 岗巴县| 五河县| 溆浦县| 华容县| 衡阳县| 舒城县| 静海县| 全州县| 新津县| 上高县| 厦门市| 图木舒克市| 阿荣旗| 定日县| 鹤峰县| 福鼎市| 繁昌县| 育儿| 河池市| 固始县| 镇宁| 大渡口区| 平乐县| 遵义市| 广平县| 北流市| 鄂温| 普陀区| 中方县| 攀枝花市| 行唐县| 三明市| 霍邱县| 阳谷县| 高要市| 绥阳县| 邻水| 洛阳市|