1. 程式人生 > 其它 >【Python】基礎學習(六)多執行緒學習

【Python】基礎學習(六)多執行緒學習

程序與執行緒的區別

  程序是資源分配的最小單位,執行緒是CPU排程的最小單位

  執行緒在程序下行進;執行緒無地址空間,它包括在程序的地址空間裡;

  一個程序可以包含多個執行緒;

  不同程序間資料很難共享;

  同一程序下不同執行緒間資料很易共享;

  程序要比執行緒消耗更多的計算機資源;

  程序間不會相互影響,一個執行緒掛掉將導致整個程序掛掉;

  程序可以拓展到多機,程序最多適合多核;

  程序使用的記憶體地址可以上鎖,即一個執行緒使用某些共享記憶體時,其他執行緒必須等它結束,才能使用這一塊記憶體;

  程序使用的記憶體地址可以限定使用量;

函式呼叫加括號和不加括號的區別

  函式加括號是指對此函式的呼叫

  函式不加括號是指呼叫函式本身(的記憶體地址)

import time
def task():
    print(time.time())
task()
print(task())
print(task)
1637464945.9630685
1637464945.9630685
None
<function task at 0x0000023412191E18>

執行緒執行

  兩執行緒同時執行,但是時間差的程式碼執行不會等兩個執行緒直線完之後在執行,而是和執行緒同時執行。

import threading
import time
def task():
print(time.time())
time.sleep(5)
print("---------------------------------")
def main():
start_time = time.time()
thread1 = threading.Thread(target=task)
thread2 = threading.Thread(target=task)
thread1.start()
thread2.start()
end_time = time.time()
print(end_time-start_time) #時間差的程式碼
if __name__ == '__main__':
main()

1637465538.072043
1637465538.072043
0.0009961128234863281
---------------------------------
---------------------------------

  在兩個執行緒後面,加了join()之後,執行緒1和執行緒2執行完之後,再執行主執行緒。

import threading
import time
def task():
    print(time.time())
    time.sleep(5)
    print("---------------------------------")
def main():
    start_time 
= time.time() thread1 = threading.Thread(target=task) thread2 = threading.Thread(target=task) thread1.start() thread2.start() thread1.join() #讓其他執行緒等待自己執行完成 thread2.join() end_time = time.time() print(end_time-start_time) if __name__ == '__main__': main()
1637465832.2290647
1637465832.2290647
---------------------------------
---------------------------------
5.008389472961426

  GIL鎖 【全域性直譯器鎖】在同一時刻,只能有一個執行緒執行。每個執行緒在執行的過程中都需要先獲取GIL,保證同一時刻只有一個執行緒在執行,目的是解決多執行緒同時競爭程式中的全域性變數而出現的執行緒安全問題。它並不是python語言的特性,僅僅是由於歷史的原因在CPython直譯器中難以移除,因為python語言執行環境大部分預設在CPython直譯器中。

  GIL面試題參考答案:

    Python語言和GIL沒有什麼關係。僅僅是由於歷史原因在Cpython虛擬機器(直譯器),難以移除GIL。
    GIL:全域性直譯器鎖。每個執行緒在執行的過程都需要先獲取GIL,保證同一時刻只有一個執行緒可以執行程式碼。
    執行緒釋放GIL鎖的情況: 在IO操作等可能會引起阻塞的system call之前,可以暫時釋放GIL,但在執行完畢後,必須重新獲取GIL       Python 3.x使用計時器(執行時間達到閾值後,當前執行緒釋放GIL)或Python 2.x,tickets計數達到100。
    Python使用多程序是可以利用多核的CPU資源的。
    多執行緒爬取比單執行緒效能有提升,因為遇到IO阻塞會自動釋放GIL鎖。
    ————————————————
    原文連結:https://blog.csdn.net/qq_40808154/article/details/89398076

  總結下來:如果不用sleep函式,其他方法執行的話,會發現,執行緒執行順序是等第一個執行緒執行完之後,在執行第二個執行緒的,統一程序內,只能執行一個執行緒

python 可呼叫物件:

  使用者自定義的函式:使用def語句或者lambda表示式建立的函式。

  內建函式:使用C語言實現的函式,如len、sum或者time.strftime

  內建方法:使用C語言實現的方法,如dict.get()

  類方法:在類的定義體中定義的函式

  類:在呼叫類時會執行類的__new__方法建立一個例項,然後執行__init__方法,初始化例項,最後把例項返回給呼叫方。Python中沒有new運算子,所以呼叫類相當於呼叫函式。

  類的例項:如果類定義了__call__方法,那麼它的例項可以作為函式進行呼叫。並且__call__方法可以進行自定義重寫。

  生成器函式:使用yield關鍵字的函式或方法。呼叫生成器函式返回的是生成器物件。