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

詳解python多線程、鎖、event事件機(jī)制的簡單使用

 更新時間:2018年04月27日 10:14:32   作者:君惜  
這篇文章主要介紹了詳解python多線程、鎖、event事件機(jī)制的簡單使用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

線程和進(jìn)程

1、線程共享創(chuàng)建它的進(jìn)程的地址空間,進(jìn)程有自己的地址空間

2、線程可以訪問進(jìn)程所有的數(shù)據(jù),線程可以相互訪問

3、線程之間的數(shù)據(jù)是獨(dú)立的

4、子進(jìn)程復(fù)制線程的數(shù)據(jù)

5、子進(jìn)程啟動后是獨(dú)立的 ,父進(jìn)程只能殺掉子進(jìn)程,而不能進(jìn)行數(shù)據(jù)交換

6、修改線程中的數(shù)據(jù),都是會影響其他的線程,而對于進(jìn)程的更改,不會影響子進(jìn)程

threading.Thread

Thread 是threading模塊中最重要的類之一,可以使用它來創(chuàng)建線程。有兩種方式來創(chuàng)建線程:一種是通過繼承Thread類,重寫它的run方法;另一種是創(chuàng)建一個threading.Thread對象,在它的初始化函數(shù)(__init__)中將可調(diào)用對象作為參數(shù)傳入。
先來看看通過繼承threading.Thread類來創(chuàng)建線程的例子:

import threading
import time

class MyThread(threading.Thread):
 def __init__(self, arg):
  # super(MyThread, self).__init__() # 新式類繼承原有方法寫法
  threading.Thread.__init__(self)
  self.arg = arg

 def run(self):
  time.sleep(2)
  print(self.arg)

for i in range(10):
 thread = MyThread(i)
 print(thread.name)
 thread.start()

另外一種創(chuàng)建線程的方法:

import threading
import time

def process(arg):
 time.sleep(2)
 print(arg)

for i in range(10):
 t = threading.Thread(target=process, args=(i,))
 print(t.name)
 t.start()

Thread類還定義了以下常用方法與屬性:

Thread.getName() 獲取線程名稱

Thread.setName() 設(shè)置線程名稱

Thread.name 線程名稱

Thread.ident 獲取線程的標(biāo)識符。線程標(biāo)識符是一個非零整數(shù),只有在調(diào)用了start()方法之后該屬性才有效,否則它只返回None

判斷線程是否是激活的(alive)。從調(diào)用start()方法啟動線程,到run()方法執(zhí)行完畢或遇到未處理異常而中斷 這段時間內(nèi),線程是激活的

Thread.is_alive()
Thread.isAlive()

Thread.join([timeout]) 調(diào)用Thread.join將會使主調(diào)線程堵塞,直到被調(diào)用線程運(yùn)行結(jié)束或超時。參數(shù)timeout是一個數(shù)值類型,表示超時時間,如果未提供該參數(shù),那么主調(diào)線程將一直堵塞到被調(diào)線程結(jié)束

Python GIL(Global Interpreter Lock)

GIL并不是Python的特性,它是在實(shí)現(xiàn)Python解析器(CPython)時所引入的一個概念。就好比C++是一套語言(語法)標(biāo)準(zhǔn),但是可以用不同的編譯器來編譯成可執(zhí)行代碼。有名的編譯器例如GCC,INTEL C++,Visual C++等。Python也一樣,同樣一段代碼可以通過CPython,PyPy,Psyco等不同的Python執(zhí)行環(huán)境來執(zhí)行。像其中的JPython就沒有GIL。然而因?yàn)镃Python是大部分環(huán)境下默認(rèn)的Python執(zhí)行環(huán)境。所以在很多人的概念里CPython就是Python,也就想當(dāng)然的把GIL歸結(jié)為Python語言的缺陷。所以這里要先明確一點(diǎn):GIL并不是Python的特性,Python完全可以不依賴于GIL。

線程鎖的使用:

# 鎖:GIL 全局解釋器 它是為了保證線程在運(yùn)行過程中不被搶占
number = 0
lock = threading.RLock() # 創(chuàng)建鎖


def run(num):
 lock.acquire() # 加鎖
 global number
 number += 1
 print(number)
 time.sleep(2)
 lock.release() # 釋放鎖

for i in range(10):
 t = threading.Thread(target=run, args=(i, ))
 t.start()

Join & Daemon

主線程A中,創(chuàng)建了子線程B,并且在主線程A中調(diào)用了B.setDaemon(),這個的意思是,把主線程A設(shè)置為守護(hù)線程,這時候,要是主線程A執(zhí)行結(jié)束了,就不管子線程B是否完成,一并和主線程A退出.這就是setDaemon方法的含義,這基本和join是相反的。此外,還有個要特別注意的:必須在start() 方法調(diào)用之前設(shè)置,如果不設(shè)置為守護(hù)線程,程序會被無限掛起。

class MyThread1(threading.Thread):
 def __init__(self):
  threading.Thread.__init__(self)

 def run(self):
  print("thread start")
  time.sleep(3)
  print('thread end')

print('main start')
thread1 = MyThread1()
# thread1.setDaemon(True)  # 設(shè)置子線程是否跟隨主線程一起結(jié)束
thread1.start()
time.sleep(1)
print('satrt join')
# thread1.join() # 使主線程阻塞,直至子線程運(yùn)行完畢再繼續(xù)主線程
print('end join')
def run(n):
 print('[%s]------running----\n' % n)
 time.sleep(2)
 print('--done--')


def main():
 for i in range(5):
  t = threading.Thread(target=run, args=[i,])
  t.start()
  # t.join()
  print('starting thread', t.getName())


m = threading.Thread(target=main,args=[])
# m.setDaemon(True) # 將主線程設(shè)置為Daemon線程,它退出時,其它子線程會同時退出,不管是否執(zhí)行完任務(wù)
m.start()
# m.join() # 使主線程阻塞,直至子線程運(yùn)行完畢再繼續(xù)主線程
print("---main thread done----")

線程鎖(互斥鎖Mutex)

一個進(jìn)程下可以啟動多個線程,多個線程共享父進(jìn)程的內(nèi)存空間,也就意味著每個線程可以訪問同一份數(shù)據(jù),此時,如果2個線程同時要修改同一份數(shù)據(jù),會出現(xiàn)什么狀況?

num = 100 # 設(shè)定一個共享變量
def subNum():
 global num # 在每個線程中都獲取這個全局變量
 print('--get num:', num)
 time.sleep(2)
 num -= 1 # 對此公共變量進(jìn)行-1操作
thread_list = []
for i in range(100):
 t = threading.Thread(target=subNum)
 t.start()
 thread_list.append(t)
for t in thread_list: # 等待所有線程執(zhí)行完畢
 t.join()
print('final num:', num)
# 加鎖版本
def subNum():
 global num # 在每個線程中都獲取這個全局變量
 print('--get num:', num)
 time.sleep(1)
 lock.acquire() # 修改數(shù)據(jù)前加鎖
 num -= 1 # 對此公共變量進(jìn)行-1操作
 lock.release() # 修改后釋放

num = 100 # 設(shè)定一個共享變量
thread_list = []
lock = threading.Lock() # 生成全局鎖
for i in range(100):
 t = threading.Thread(target=subNum)
 t.start()
 thread_list.append(t)
for t in thread_list: # 等待所有線程執(zhí)行完畢
 t.join()
print('final num:', num)

Rlock與Lock的區(qū)別:

RLock允許在同一線程中被多次acquire。而Lock卻不允許這種情況。否則會出現(xiàn)死循環(huán),程序不知道解哪一把鎖。注意:如果使用RLock,那么acquire和release必須成對出現(xiàn),即調(diào)用了n次acquire,必須調(diào)用n次的release才能真正釋放所占用的鎖

Events

Python提供了Event對象用于線程間通信,它是由線程設(shè)置的信號標(biāo)志,如果信號標(biāo)志位真,則其他線程等待直到信號接觸。
Event對象實(shí)現(xiàn)了簡單的線程通信機(jī)制,它提供了設(shè)置信號,清除信號,等待等用于實(shí)現(xiàn)線程間的通信。

event = threading.Event() 創(chuàng)建一個event

1 設(shè)置信號
event.set()

使用Event的set()方法可以設(shè)置Event對象內(nèi)部的信號標(biāo)志為真。Event對象提供了isSet()方法來判斷其內(nèi)部信號標(biāo)志的狀態(tài)。
當(dāng)使用event對象的set()方法后,isSet()方法返回真

2 清除信號
event.clear()

使用Event對象的clear()方法可以清除Event對象內(nèi)部的信號標(biāo)志,即將其設(shè)為假,當(dāng)使用Event的clear方法后,isSet()方法返回假

3 等待
event.wait()

Event對象wait的方法只有在內(nèi)部信號為真的時候才會很快的執(zhí)行并完成返回。當(dāng)Event對象的內(nèi)部信號標(biāo)志位假時,
則wait方法一直等待到其為真時才返回。也就是說必須set新號標(biāo)志位真

def do(event):
 print('start')
 event.wait()
 print('execute')

event_obj = threading.Event()
for i in range(10):
 t = threading.Thread(target=do, args=(event_obj,))
 t.start()

event_obj.clear()
inp = input('輸入內(nèi)容:')
if inp == 'true':
 event_obj.set()

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

相關(guān)文章

  • Python Tricks 使用 pywinrm 遠(yuǎn)程控制 Windows 主機(jī)的方法

    Python Tricks 使用 pywinrm 遠(yuǎn)程控制 Windows 主機(jī)的方法

    這篇文章主要介紹了Python Tricks 使用 pywinrm 遠(yuǎn)程控制 Windows 主機(jī)的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Python?turtle庫(繪制螺旋正方形)

    Python?turtle庫(繪制螺旋正方形)

    這篇文章主要介紹了Python?turtle庫(繪制螺旋正方形),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Pycharm使用時會出現(xiàn)的問題之cv2無法安裝解決

    Pycharm使用時會出現(xiàn)的問題之cv2無法安裝解決

    這篇文章主要介紹了Pycharm使用時會出現(xiàn)的問題之cv2無法安裝解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • python中property和setter裝飾器用法

    python中property和setter裝飾器用法

    今天小編就為大家分享一篇python中property和setter裝飾器用法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • python如何使用raise拋出自定義異常

    python如何使用raise拋出自定義異常

    這篇文章主要介紹了python如何使用raise拋出自定義異常問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Python中獲取當(dāng)前線程名字的方法及多線程編程實(shí)踐記錄

    Python中獲取當(dāng)前線程名字的方法及多線程編程實(shí)踐記錄

    本文介紹了在Python中獲取當(dāng)前線程的名字的方法,并探討了其在多線程編程中的重要性和實(shí)際應(yīng)用,通過兩個實(shí)際的代碼示例,展示了如何利用多線程來并行計(jì)算斐波那契數(shù)列和下載文件,以提高程序的性能和效率,感興趣的朋友一起看看吧
    2024-04-04
  • Python解析JSON數(shù)據(jù)的方法簡單例子

    Python解析JSON數(shù)據(jù)的方法簡單例子

    這篇文章主要給大家介紹了關(guān)于Python解析JSON數(shù)據(jù)的方法,解析JSON文件是Python中非常常見的操作,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-09-09
  • Windows11使用Cpython?編譯文件報(bào)錯?error:?Unable?to?find?vcvarsall.bat?完美解決方法

    Windows11使用Cpython?編譯文件報(bào)錯?error:?Unable?to?find?vcvars

    這篇文章主要介紹了Windows11使用Cpython編譯文件報(bào)錯error:Unable?to find?vcvarsall.bat完美解決方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • OpenCV結(jié)合selenium實(shí)現(xiàn)滑塊驗(yàn)證碼

    OpenCV結(jié)合selenium實(shí)現(xiàn)滑塊驗(yàn)證碼

    本文主要介紹了OpenCV結(jié)合selenium實(shí)現(xiàn)滑塊驗(yàn)證碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • pandas重復(fù)行刪除操作df.drop_duplicates和df.duplicated的區(qū)別

    pandas重復(fù)行刪除操作df.drop_duplicates和df.duplicated的區(qū)別

    本文主要介紹了pandas重復(fù)行刪除操作df.drop_duplicates和df.duplicated的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08

最新評論

中西区| 潼南县| 清流县| 普兰县| 磴口县| 南陵县| 吉木乃县| 福安市| 湛江市| 巴南区| 府谷县| 玉门市| 阿图什市| 晋州市| 图木舒克市| 高雄市| 鲁山县| 古田县| 东乡| 普格县| 长寿区| 包头市| 崇文区| 洛扎县| 衡阳县| 德清县| 疏勒县| 墨玉县| 广东省| 鄂托克前旗| 原阳县| 曲周县| 武鸣县| 海安县| 萨嘎县| 门头沟区| 林州市| 白玉县| 盘山县| 大关县| 漳平市|