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

python多線程超詳細(xì)詳解

 更新時間:2021年04月07日 16:48:36   作者:笨小孩哈哈  
這篇文章主要介紹了python多線程超詳細(xì)詳解,多線程這個知識點非常重要,想了解的同學(xué)可以參考下

python中的多線程是一個非常重要的知識點,今天為大家對多線程進行詳細(xì)的說明,代碼中的注釋有多線程的知識點還有測試用的實例。

import threading
from threading import Lock,Thread
import time,os


'''
          python多線程詳解
  什么是線程?
  線程也叫輕量級進程,是操作系統(tǒng)能夠進行運算調(diào)度的最小單位,它被包涵在進程之中,是進程中的實際運作單位。
  線程自己不擁有系統(tǒng)資源,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個進程的其他線程共享進程所
  擁有的全部資源。一個線程可以創(chuàng)建和撤銷另一個線程,同一個進程中的多個線程之間可以并發(fā)執(zhí)行
'''

'''
 為什么要使用多線程?
 線程在程序中是獨立的、并發(fā)的執(zhí)行流。與分隔的進程相比,進程中線程之間的隔離程度要小,它們共享內(nèi)存、文件句柄
 和其他進程應(yīng)有的狀態(tài)。
 因為線程的劃分尺度小于進程,使得多線程程序的并發(fā)性高。進程在執(zhí)行過程之中擁有獨立的內(nèi)存單元,而多個線程共享
 內(nèi)存,從而極大的提升了程序的運行效率。
 線程比進程具有更高的性能,這是由于同一個進程中的線程都有共性,多個線程共享一個進程的虛擬空間。線程的共享環(huán)境
 包括進程代碼段、進程的共有數(shù)據(jù)等,利用這些共享的數(shù)據(jù),線程之間很容易實現(xiàn)通信。
 操作系統(tǒng)在創(chuàng)建進程時,必須為改進程分配獨立的內(nèi)存空間,并分配大量的相關(guān)資源,但創(chuàng)建線程則簡單得多。因此,使用多線程
 來實現(xiàn)并發(fā)比使用多進程的性能高得要多。
'''

'''
 總結(jié)起來,使用多線程編程具有如下幾個優(yōu)點:
 進程之間不能共享內(nèi)存,但線程之間共享內(nèi)存非常容易。
 操作系統(tǒng)在創(chuàng)建進程時,需要為該進程重新分配系統(tǒng)資源,但創(chuàng)建線程的代價則小得多。因此使用多線程來實現(xiàn)多任務(wù)并發(fā)執(zhí)行比使用多進程的效率高
 python語言內(nèi)置了多線程功能支持,而不是單純地作為底層操作系統(tǒng)的調(diào)度方式,從而簡化了python的多線程編程。
'''


'''
 普通創(chuàng)建方式
'''
# def run(n):
#  print('task',n)
#  time.sleep(1)
#  print('2s')
#  time.sleep(1)
#  print('1s')
#  time.sleep(1)
#  print('0s')
#  time.sleep(1)
#
# if __name__ == '__main__':
#  t1 = threading.Thread(target=run,args=('t1',))  # target是要執(zhí)行的函數(shù)名(不是函數(shù)),args是函數(shù)對應(yīng)的參數(shù),以元組的形式存在
#  t2 = threading.Thread(target=run,args=('t2',))
#  t1.start()
#  t2.start()


'''
 自定義線程:繼承threading.Thread來定義線程類,其本質(zhì)是重構(gòu)Thread類中的run方法
'''
# class MyThread(threading.Thread):
#  def __init__(self,n):
#   super(MyThread,self).__init__() #重構(gòu)run函數(shù)必須寫
#   self.n = n
#
#  def run(self):
#   print('task',self.n)
#   time.sleep(1)
#   print('2s')
#   time.sleep(1)
#   print('1s')
#   time.sleep(1)
#   print('0s')
#   time.sleep(1)
#
# if __name__ == '__main__':
#  t1 = MyThread('t1')
#  t2 = MyThread('t2')
#  t1.start()
#  t2.start()


'''
 守護線程
 下面這個例子,這里使用setDaemon(True)把所有的子線程都變成了主線程的守護線程,
 因此當(dāng)主線程結(jié)束后,子線程也會隨之結(jié)束,所以當(dāng)主線程結(jié)束后,整個程序就退出了。
 所謂'線程守護',就是主線程不管該線程的執(zhí)行情況,只要是其他子線程結(jié)束且主線程執(zhí)行完畢,主線程都會關(guān)閉。也就是說:主線程不等待該守護線程的執(zhí)行完再去關(guān)閉。
'''
# def run(n):
#  print('task',n)
#  time.sleep(1)
#  print('3s')
#  time.sleep(1)
#  print('2s')
#  time.sleep(1)
#  print('1s')
#
# if __name__ == '__main__':
#  t=threading.Thread(target=run,args=('t1',))
#  t.setDaemon(True)
#  t.start()
#  print('end')
'''
 通過執(zhí)行結(jié)果可以看出,設(shè)置守護線程之后,當(dāng)主線程結(jié)束時,子線程也將立即結(jié)束,不再執(zhí)行
'''

'''
 主線程等待子線程結(jié)束
 為了讓守護線程執(zhí)行結(jié)束之后,主線程再結(jié)束,我們可以使用join方法,讓主線程等待子線程執(zhí)行
'''
# def run(n):
#  print('task',n)
#  time.sleep(2)
#  print('5s')
#  time.sleep(2)
#  print('3s')
#  time.sleep(2)
#  print('1s')
# if __name__ == '__main__':
#  t=threading.Thread(target=run,args=('t1',))
#  t.setDaemon(True) #把子線程設(shè)置為守護線程,必須在start()之前設(shè)置
#  t.start()
#  t.join()  #設(shè)置主線程等待子線程結(jié)束
#  print('end')


'''
 多線程共享全局變量
 線程時進程的執(zhí)行單元,進程時系統(tǒng)分配資源的最小執(zhí)行單位,所以在同一個進程中的多線程是共享資源的
'''
# g_num = 100
# def work1():
#  global g_num
#  for i in range(3):
#   g_num+=1
#  print('in work1 g_num is : %d' % g_num)
#
# def work2():
#  global g_num
#  print('in work2 g_num is : %d' % g_num)
#
# if __name__ == '__main__':
#  t1 = threading.Thread(target=work1)
#  t1.start()
#  time.sleep(1)
#  t2=threading.Thread(target=work2)
#  t2.start()


'''
  由于線程之間是進行隨機調(diào)度,并且每個線程可能只執(zhí)行n條執(zhí)行之后,當(dāng)多個線程同時修改同一條數(shù)據(jù)時可能會出現(xiàn)臟數(shù)據(jù),
 所以出現(xiàn)了線程鎖,即同一時刻允許一個線程執(zhí)行操作。線程鎖用于鎖定資源,可以定義多個鎖,像下面的代碼,當(dāng)需要獨占
 某一個資源時,任何一個鎖都可以鎖定這個資源,就好比你用不同的鎖都可以把這個相同的門鎖住一樣。
  由于線程之間是進行隨機調(diào)度的,如果有多個線程同時操作一個對象,如果沒有很好地保護該對象,會造成程序結(jié)果的不可預(yù)期,
 我們因此也稱為“線程不安全”。
  為了防止上面情況的發(fā)生,就出現(xiàn)了互斥鎖(Lock)
'''
# def work():
#  global n
#  lock.acquire()
#  temp = n
#  time.sleep(0.1)
#  n = temp-1
#  lock.release()
#
#
# if __name__ == '__main__':
#  lock = Lock()
#  n = 100
#  l = []
#  for i in range(100):
#   p = Thread(target=work)
#   l.append(p)
#   p.start()
#  for p in l:
#   p.join()


'''
 遞歸鎖:RLcok類的用法和Lock類一模一樣,但它支持嵌套,在多個鎖沒有釋放的時候一般會使用RLock類
'''
# def func(lock):
#  global gl_num
#  lock.acquire()
#  gl_num += 1
#  time.sleep(1)
#  print(gl_num)
#  lock.release()
#
#
# if __name__ == '__main__':
#  gl_num = 0
#  lock = threading.RLock()
#  for i in range(10):
#   t = threading.Thread(target=func,args=(lock,))
#   t.start()


'''
 信號量(BoundedSemaphore類)
 互斥鎖同時只允許一個線程更改數(shù)據(jù),而Semaphore是同時允許一定數(shù)量的線程更改數(shù)據(jù),比如廁所有3個坑,
 那最多只允許3個人上廁所,后面的人只能等里面有人出來了才能再進去
'''
# def run(n,semaphore):
#  semaphore.acquire() #加鎖
#  time.sleep(3)
#  print('run the thread:%s\n' % n)
#  semaphore.release() #釋放
#
#
# if __name__== '__main__':
#  num=0
#  semaphore = threading.BoundedSemaphore(5) #最多允許5個線程同時運行
#  for i in range(22):
#   t = threading.Thread(target=run,args=('t-%s' % i,semaphore))
#   t.start()
#  while threading.active_count() !=1:
#   pass
#  else:
#   print('----------all threads done-----------')

'''
 python線程的事件用于主線程控制其他線程的執(zhí)行,事件是一個簡單的線程同步對象,其主要提供以下的幾個方法:
  clear將flag設(shè)置為 False
  set將flag設(shè)置為 True
  is_set判斷是否設(shè)置了flag
  wait會一直監(jiān)聽flag,如果沒有檢測到flag就一直處于阻塞狀態(tài)
 事件處理的機制:全局定義了一個Flag,當(dāng)Flag的值為False,那么event.wait()就會阻塞,當(dāng)flag值為True,
 那么event.wait()便不再阻塞
'''
event = threading.Event()
def lighter():
 count = 0
 event.set()   #初始者為綠燈
 while True:
  if 5 < count <=10:
   event.clear() #紅燈,清除標(biāo)志位
   print("\33[41;lmred light is on...\033[0m]")
  elif count > 10:
   event.set() #綠燈,設(shè)置標(biāo)志位
   count = 0
  else:
   print('\33[42;lmgreen light is on...\033[0m')

  time.sleep(1)
  count += 1


def car(name):
 while True:
  if event.is_set():  #判斷是否設(shè)置了標(biāo)志位
   print('[%s] running.....'%name)
   time.sleep(1)
  else:
   print('[%s] sees red light,waiting...'%name)
   event.wait()
   print('[%s] green light is on,start going...'%name)


# startTime = time.time()
light = threading.Thread(target=lighter,)
light.start()

car = threading.Thread(target=car,args=('MINT',))
car.start()
endTime = time.time()
# print('用時:',endTime-startTime)

'''
       GIL 全局解釋器
  在非python環(huán)境中,單核情況下,同時只能有一個任務(wù)執(zhí)行。多核時可以支持多個線程同時執(zhí)行。但是在python中,無論有多少個核
  同時只能執(zhí)行一個線程。究其原因,這就是由于GIL的存在導(dǎo)致的。
  GIL的全程是全局解釋器,來源是python設(shè)計之初的考慮,為了數(shù)據(jù)安全所做的決定。某個線程想要執(zhí)行,必須先拿到GIL,我們可以
  把GIL看做是“通行證”,并且在一個python進程之中,GIL只有一個。拿不到線程的通行證,并且在一個python進程中,GIL只有一個,
  拿不到通行證的線程,就不允許進入CPU執(zhí)行。GIL只在cpython中才有,因為cpython調(diào)用的是c語言的原生線程,所以他不能直接操
  作cpu,而只能利用GIL保證同一時間只能有一個線程拿到數(shù)據(jù)。而在pypy和jpython中是沒有GIL的
  python在使用多線程的時候,調(diào)用的是c語言的原生過程。
'''
'''
       python針對不同類型的代碼執(zhí)行效率也是不同的
  1、CPU密集型代碼(各種循環(huán)處理、計算等),在這種情況下,由于計算工作多,ticks技術(shù)很快就會達到閥值,然后出發(fā)GIL的
  釋放與再競爭(多個線程來回切換當(dāng)然是需要消耗資源的),所以python下的多線程對CPU密集型代碼并不友好。
  2、IO密集型代碼(文件處理、網(wǎng)絡(luò)爬蟲等設(shè)計文件讀寫操作),多線程能夠有效提升效率(單線程下有IO操作會進行IO等待,
  造成不必要的時間浪費,而開啟多線程能在線程A等待時,自動切換到線程B,可以不浪費CPU的資源,從而能提升程序的執(zhí)行
  效率)。所以python的多線程對IO密集型代碼比較友好。
'''
'''
 主要要看任務(wù)的類型,我們把任務(wù)分為I/O密集型和計算密集型,而多線程在切換中又分為I/O切換和時間切換。如果任務(wù)屬于是I/O密集型,
 若不采用多線程,我們在進行I/O操作時,勢必要等待前面一個I/O任務(wù)完成后面的I/O任務(wù)才能進行,在這個等待的過程中,CPU處于等待
 狀態(tài),這時如果采用多線程的話,剛好可以切換到進行另一個I/O任務(wù)。這樣就剛好可以充分利用CPU避免CPU處于閑置狀態(tài),提高效率。但是
 如果多線程任務(wù)都是計算型,CPU會一直在進行工作,直到一定的時間后采取多線程時間切換的方式進行切換線程,此時CPU一直處于工作狀態(tài),
 此種情況下并不能提高性能,相反在切換多線程任務(wù)時,可能還會造成時間和資源的浪費,導(dǎo)致效能下降。這就是造成上面兩種多線程結(jié)果不能的解釋。
結(jié)論:I/O密集型任務(wù),建議采取多線程,還可以采用多進程+協(xié)程的方式(例如:爬蟲多采用多線程處理爬取的數(shù)據(jù));對于計算密集型任務(wù),python此時就不適用了。
'''

到此這篇關(guān)于python多線程超詳細(xì)詳解的文章就介紹到這了,更多相關(guān)python多線程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python讀取英文文件并記錄每個單詞出現(xiàn)次數(shù)后降序輸出示例

    Python讀取英文文件并記錄每個單詞出現(xiàn)次數(shù)后降序輸出示例

    這篇文章主要介紹了Python讀取英文文件并記錄每個單詞出現(xiàn)次數(shù)后降序輸出,涉及Python文件讀取、字符串替換、分割以及字典遍歷、排序等相關(guān)操作技巧,需要的朋友可以參考下
    2018-06-06
  • 解決nohup執(zhí)行python程序log文件寫入不及時的問題

    解決nohup執(zhí)行python程序log文件寫入不及時的問題

    今天小編就為大家分享一篇解決nohup執(zhí)行python程序log文件寫入不及時的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • python 缺失值處理的方法(Imputation)

    python 缺失值處理的方法(Imputation)

    這篇文章主要介紹了python 缺失值處理的方法(Imputation),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • python 進程 進程池 進程間通信實現(xiàn)解析

    python 進程 進程池 進程間通信實現(xiàn)解析

    這篇文章主要介紹了python 進程 進程池 進程間通信實現(xiàn)解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • 詳解Python循環(huán)作用域與閉包

    詳解Python循環(huán)作用域與閉包

    這篇文章主要介紹了Python循環(huán)作用域與閉包,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Python tabulate結(jié)合loguru打印出美觀方便的日志記錄

    Python tabulate結(jié)合loguru打印出美觀方便的日志記錄

    在開發(fā)過程中經(jīng)常碰到在本地環(huán)境無法完成聯(lián)調(diào)測試的情況,必須到統(tǒng)一的聯(lián)機環(huán)境對接其他系統(tǒng)測試。往往是出現(xiàn)了BUG難以查找數(shù)據(jù)記錄及時定位到錯誤出現(xiàn)的位置。本文將利用tabulate結(jié)合loguru實現(xiàn)打印出美觀方便的日志記錄,需要的可以參考一下
    2022-10-10
  • 用 Python 定義 Schema 并生成 Parquet 文件詳情

    用 Python 定義 Schema 并生成 Parquet 文件詳情

    本文將演示兩個例子,一個是沒有層級的兩個字段,另一個是含于嵌套級別的字段,將要使用到的 Python 模塊有 pandas 和 pyarrow,感興趣是我小伙伴請和小編一起學(xué)習(xí)下面文章內(nèi)容吧
    2021-09-09
  • python正則表達式實例代碼

    python正則表達式實例代碼

    這篇文章主要介紹了python正則表達式的一些實例代碼,方便學(xué)習(xí)python的朋友,需要的朋友可以參考下
    2020-03-03
  • Python依賴管理及打包工具Poetry使用規(guī)范

    Python依賴管理及打包工具Poetry使用規(guī)范

    這篇文章主要為大家介紹了Python依賴管理及打包工具Poetry的依賴規(guī)范,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2021-09-09
  • python dataframe NaN處理方式

    python dataframe NaN處理方式

    今天小編就為大家分享一篇python dataframe NaN處理方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12

最新評論

天柱县| 四子王旗| 兰溪市| 余干县| 奉化市| 游戏| 谢通门县| 郧西县| 二连浩特市| 分宜县| 桓台县| 遂宁市| 吉木乃县| 电白县| 文昌市| 韶关市| 旬阳县| 墨竹工卡县| 平江县| 宣城市| 霍林郭勒市| 松江区| 宁安市| 太谷县| 曲松县| 师宗县| 象州县| 龙岩市| 三都| 建始县| 于都县| 拜城县| 分宜县| 米脂县| 上栗县| 香河县| 嘉祥县| 富民县| 盘锦市| 惠安县| 丰顺县|